С помощью Relay очень легко настроить разбиение на страницы, однако есть небольшая деталь, которая мне непонятна.
обе соответствующие части моего кода отмечены комментариями, другой код предназначен для дополнительного контекста.
const postType = new GraphQLObjectType({
name: 'Post',
fields: () => ({
id: globalIdField('Post'),
title: {
type: GraphQLString
},
}),
interfaces: [nodeInterface],
})
const userType = new GraphQLObjectType({
name: 'User',
fields: () => ({
id: globalIdField('User'),
email: {
type: GraphQLString
},
posts: {
type: postConnection,
args: connectionArgs,
resolve: async (user, args) => {
// getUserPosts() is in next code block -> it gets the data from db
// I pass args (e.g "first", "after" etc) and user id (to get only user posts)
const posts = await getUserPosts(args, user._id)
return connectionFromArray(posts, args)
}
},
}),
interfaces: [nodeInterface],
})
const {connectionType: postConnection} =
connectionDefinitions({name: 'Post', nodeType: postType})
exports.getUserPosts = async (args, userId) => {
try {
// using MongoDB and Mongoose but question is relevant with every db
// .limit() -> how many posts to return
const posts = await Post.find({author: userId}).limit(args.first).exec()
return posts
} catch (err) {
return err
}
}
Причина моего замешательства:
- Если я передам аргумент
first
и использую его в запросе БД для ограничения возвращаемых результатов,hasNextPage
будет всегдаfalse
. Это эффективно, но нарушаетhasNextPage
(hasPreviousPage
, если вы используетеlast
) - If I don't pass the
first
argument and don't use it in db query to limit returned results,hasNextPage
is working as expected but it will return all the items I queried (could be thousands)- Even if database is on same machine (which isn't the case for bigger apps), this seems very, very, very inefficient and awful. Please prove me that Im wrong!
- Насколько я знаю, GraphQL не имеет кэширования на стороне сервера, поэтому нет смысла возвращать все результаты (даже если бы это было так, пользователи не просматривают 100% контента)
В чем здесь логика?
Одно из решений, которое приходит мне на ум, состоит в том, чтобы добавить +1
к значению first
в getUserPosts
, это приведет к извлечению одного лишнего элемента, и hasNextPage
, вероятно, сработает. Но это похоже на взлом, и всегда возвращается лишний элемент — он будет расти относительно быстро, если будет много connections
и запросов.
Ожидается ли, что мы взломаем его таким образом? Ожидается ли возврат всех результатов?
Или я неправильно понял всю связь между базой данных и GrahpQL/Relay?
Что, если бы я использовал FB DataLoader и Redis? Изменит ли это что-нибудь в этой логике?