Două strategii: bazată pe offset (limit/offset) și bazată pe cursor. GraphQL nu are paginare integrată, dar standardul comunității este specificația Relay Connection, care formalizează paginarea cu cursor.
Două strategii: bazată pe offset (limit/offset) și bazată pe cursor. GraphQL nu are paginare integrată, dar standardul comunității este specificația Relay Connection, care formalizează paginarea cu cursor.
items(limit: 10, offset: 20)) este simplu, dar se sparge pe date live: dacă un rând este inserat în timp ce utilizatorul paginează, elementele se deplasează și vezi duplicate sau goluri. De asemenea, devine lent la offset-uri adânci (baza de date tot scanează rândurile sărite).O conexiune încapsulează lista în edges (fiecare cu un cursor și un node) plus pageInfo:
type Query {
posts(first: Int!, after: String): PostConnection! # first = dimensiunea paginii, after = cursor
}
type PostConnection {
edges: [PostEdge!]!
pageInfo: PageInfo!
}
type PostEdge {
cursor: String! # token opac pentru poziția ACESTUI node
node: Post! # elementul propriu-zis
}
type PageInfo {
endCursor: String # trimite-l înapoi ca 'after' pentru pagina următoare
hasNextPage: Boolean! # ca să știe clientul când să se oprească
}
// resolver: aduce UN rând în plus ca să calculezi ieftin hasNextPage
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 },
};
Cursor-ul este opac — de obicei un base64 al cheii de sortare — așa că clienții îl tratează ca pe un token, nu ca pe un număr.
Alegerea între offset și cursor arată că înțelegi consistența sub scrieri concurente și performanța la pagini adânci. Cunoașterea formei conexiunii Relay contează deoarece clienții Apollo/Relay au tratare integrată a cache-ului pentru ea.
O bibliotecă de întrebări de interviu IT cu răspunsuri detaliate — de la Junior la Senior.
Donează