दो रणनीतियाँ: offset-based (limit/offset) और cursor-based। GraphQL में कोई built-in pagination नहीं है, लेकिन community standard Relay Connection spec है, जो cursor pagination को औपचारिक रूप देती है।
दो रणनीतियाँ: offset-based (limit/offset) और cursor-based। GraphQL में कोई built-in pagination नहीं है, लेकिन community standard Relay Connection spec है, जो cursor pagination को औपचारिक रूप देती है।
items(limit: 10, offset: 20)) सरल है लेकिन live data पर टूट जाता है: यदि user के page करते समय कोई row insert हो जाए, तो items खिसक जाते हैं और आपको duplicates या gaps दिखते हैं। यह गहरे offsets पर धीमा भी हो जाता है (DB फिर भी छोड़ी गई rows को scan करता है)।एक connection list को edges (हर एक में एक cursor और node) साथ में 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 अपारदर्शी (opaque) होता है — आमतौर पर sort key का एक base64 — इसलिए clients इसे एक number नहीं बल्कि एक token की तरह मानते हैं।
Offset बनाम cursor चुनना दिखाता है कि आप समवर्ती writes के तहत consistency और गहरे-page की performance को समझते हैं। Relay connection के आकार को जानना मायने रखता है क्योंकि Apollo/Relay clients में इसके लिए built-in cache handling होती है।
विस्तृत उत्तरों के साथ IT इंटरव्यू प्रश्नों की एक लाइब्रेरी — जूनियर से सीनियर तक।
दान करें