Dvě strategie: offsetová (limit/offset) a kurzorová. GraphQL nemá vestavěné stránkování, ale komunitním standardem je specifikace Relay Connection, která formalizuje kurzorové stránkování.
Dvě strategie: offsetová (limit/offset) a kurzorová. GraphQL nemá vestavěné stránkování, ale komunitním standardem je specifikace Relay Connection, která formalizuje kurzorové stránkování.
items(limit: 10, offset: 20)) je jednoduchý, ale selhává na živých datech: pokud se během stránkování vloží řádek, položky se posunou a uvidíte duplicity nebo mezery. Navíc je pomalý u velkých offsetů (DB stále prochází přeskočené řádky).Connection obaluje seznam do edges (každá s cursor a node) plus pageInfo:
type Query {
posts(first: Int!, after: String): PostConnection! # first = velikost stránky, after = kurzor
}
type PostConnection {
edges: [PostEdge!]!
pageInfo: PageInfo!
}
type PostEdge {
cursor: String! # neprůhledný token pro pozici TOHOTO node
node: Post! # samotná položka
}
type PageInfo {
endCursor: String # tuto hodnotu vrať zpět jako 'after' pro další stránku
hasNextPage: Boolean! # aby klient věděl, kdy přestat
}
// resolver: načti JEDEN řádek navíc, abys levně spočítal 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 },
};
Kurzor je neprůhledný — obvykle base64 řadicího klíče — takže s ním klienti zacházejí jako s tokenem, ne jako s číslem.
Volba mezi offsetem a kurzorem ukazuje, že rozumíte konzistenci při souběžných zápisech a výkonu u hlubokých stránek. Znalost tvaru Relay connection je důležitá, protože klienti Apollo/Relay pro něj mají vestavěnou obsluhu cache.
Knihovna IT otázek k pohovoru s podrobnými odpověďmi — od Junior po Senior.
Přispět