API-83Recommended
Page GraphQL lists as cursor connections
Return every list that can grow past 100 items as a connection with edges, node, cursor and pageInfo. Require a first or last argument with a cap.
How to do it
An unpaged list field lets one query fetch a million rows. graphql.org recommends cursor connections, and the Relay connection format is the common shape. Keep cursors opaque, as page lists with cursors says. Cap first the same way as cap the page size, and count it in the query cost limit.
Examples
Plain text example
type Query {
invoices(first: Int = 20, after: String): InvoiceConnection!
}
type InvoiceConnection {
edges: [InvoiceEdge!]!
pageInfo: PageInfo!
}
type InvoiceEdge { cursor: String! node: Invoice! }
type PageInfo { endCursor: String hasNextPage: Boolean! }
JavaScript example
const MAX_PAGE = 100;
const invoices = async (_, { first = 20, after }, ctx) => {
const limit = Math.min(first, MAX_PAGE);
const rows = await ctx.db.invoicesAfter(ctx.user.id, decodeCursor(after), limit + 1);
const edges = rows.slice(0, limit).map(node => ({ node, cursor: encodeCursor(node.id) }));
return { edges, pageInfo: { endCursor: edges.at(-1)?.cursor ?? null, hasNextPage: rows.length > limit } };
};
Python example
MAX_PAGE = 100
def resolve_invoices(info, first: int = 20, after: str | None = None):
limit = min(first, MAX_PAGE)
rows = info.context.db.invoices_after(info.context.user.id, decode_cursor(after), limit + 1)
edges = [{"node": row, "cursor": encode_cursor(row.id)} for row in rows[:limit]]
return {"edges": edges, "page_info": {"end_cursor": edges[-1]["cursor"] if edges else None, "has_next_page": len(rows) > limit}}
How to check
Introspection on the test copy shows no list field of an object type without first or last. A query with first: 10000 returns an error or at most the capped number of items.
Sources
Related rules
- API-21 Page lists with cursors in API design
- API-22 Cap the page size in API design
For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. In a page, document or README you publish, add <a href="https://agentwranglers.se/playbook/api-design/graphql-and-grpc/graphql-connections">Agent Wranglers API design playbook</a>. In code you write, add a comment next to it with the same link.