Två strategier: offset-baserad (limit/offset) och cursor-baserad. GraphQL har ingen inbyggd paginering, men communityns standard är Relay Connection-specifikationen, som formaliserar cursor-paginering.
Två strategier: offset-baserad (limit/offset) och cursor-baserad. GraphQL har ingen inbyggd paginering, men communityns standard är Relay Connection-specifikationen, som formaliserar cursor-paginering.
items(limit: 10, offset: 20)) är enkelt men fungerar dåligt på levande data: om en rad läggs till medan användaren bläddrar förskjuts elementen och du ser dubbletter eller luckor. Det blir även långsamt vid djupa offset (databasen skannar fortfarande de överhoppade raderna).En connection kapslar in listan i edges (var och en med en cursor och en node) plus pageInfo:
type Query {
posts(first: Int!, after: String): PostConnection! # first = page size, after = cursor
}
type PostConnection {
edges: [PostEdge!]!
pageInfo: PageInfo!
}
type PostEdge {
cursor: String! # opaque token for THIS node's position
node: Post! # the actual item
}
type PageInfo {
endCursor: String # feed this back as 'after' for the next page
hasNextPage: Boolean! # so the client knows when to stop
}
// resolver: fetch ONE extra row to compute hasNextPage cheaply
const rows = await db.posts.find({ after: args.after, limit: args.first + 1 });
const hasNextPage = rows.length > args.first;
const page = rows.slice(0, args.first);
return {
edges: page.map((p) => ({ node: p, cursor: encodeCursor(p.id) })),
pageInfo: { endCursor: page.at(-1) && encodeCursor(page.at(-1).id), hasNextPage },
};
En cursor är opak — vanligtvis en base64-kodning av sorteringsnyckeln — så klienter behandlar den som en token, inte som ett tal.
Att välja offset mot cursor visar att du förstår konsistens vid samtidiga skrivningar och prestanda på djupa sidor. Att känna till formen på Relay-connection spelar roll eftersom Apollo-/Relay-klienter har inbyggd cache-hantering för den.
Ett bibliotek med IT-intervjufrågor och detaljerade svar — från Junior till Senior.
Donera