Kaksi strategiaa: offset-pohjainen (limit/offset) ja cursor-pohjainen. GraphQL:ssä ei ole sisäänrakennettua paginointia, mutta yhteisön standardi on Relay Connection -spesifikaatio, joka formalisoi cursor-paginoinnin.
Kaksi strategiaa: offset-pohjainen (limit/offset) ja cursor-pohjainen. GraphQL:ssä ei ole sisäänrakennettua paginointia, mutta yhteisön standardi on Relay Connection -spesifikaatio, joka formalisoi cursor-paginoinnin.
items(limit: 10, offset: 20)) on yksinkertainen mutta rikkoutuu elävällä datalla: jos rivi lisätään käyttäjän selatessa, alkiot siirtyvät ja näet duplikaatteja tai aukkoja. Se myös hidastuu syvillä offseteilla (DB skannaa silti ohitetut rivit).Connection kietoo listan edgesiin (jokaisella cursor ja 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 },
};
Cursor on läpinäkymätön (opaque) — yleensä lajitteluavaimen base64 — joten clientit käsittelevät sitä tokenina, ei numerona.
Offsetin ja cursorin välillä valitseminen osoittaa, että ymmärrät konsistenssin samanaikaisten kirjoitusten aikana ja syvien sivujen suorituskyvyn. Relay-connectionin muodon tunteminen on tärkeää, koska Apollo-/Relay-clienteissä on sille valmis cache-käsittely.
Kirjasto IT-haastattelukysymyksiä yksityiskohtaisine vastauksineen — Juniorista Senioriin.
Lahjoita