Graphql schema design
Skill Amey-Thakur/AI-SKILLS/skills/apis/graphql-schema-design
Plug-and-play skills and prompts for every AI coding agent
npx -y skills add Amey-Thakur/AI-SKILLS --skill graphql-schema-designAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- 18 days oldThe repository was created 18 days ago. New is not bad, but a brand new repository carrying a familiar-sounding name is the shape a typosquat arrives in, and there has been no time for anyone else to find a problem with it.
- 4 stars4 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Design GraphQL schemas that model the domain, solve N+1 with dataloaders, and handle pagination and errors, knowing when REST wins. Use when building a GraphQL API or evaluating GraphQL against REST.
SKILL.md
3.6 KB, as published. Nobody here has run it
GraphQL schema design
GraphQL lets clients request exactly the data they need in one round trip, shaped by a typed schema. Its power (flexible client-driven queries) is also its trap (N+1 resolvers, unbounded query cost); good schema design models the domain well and defends against the failure modes GraphQL uniquely enables.
Method
- Model the schema on the domain graph, not the database. Types and their relationships reflect how the domain connects (a user has posts, a post has comments), letting clients traverse naturally: this is GraphQL's strength over REST's fixed endpoints. Design from the client's questions and the domain (see domain-driven- design), not by mechanically exposing tables.
- Solve N+1 with dataloaders from day one. GraphQL's nested resolvers naturally produce N+1 queries (resolving 100 posts, then 100 separate author queries: see n-plus-one-queries): batch and cache within a request with dataloaders (collect the IDs, fetch in one query). This is not optional optimization; it is required architecture, because the N+1 is inherent to how resolvers execute.
- Paginate with cursors via the connections pattern. Lists use cursor-based pagination (the Relay connections spec: edges, nodes, pageInfo: see api-pagination-design) for stable pagination over changing data; offset pagination breaks as items shift. Bake pagination into list fields from the start; retrofitting it is a breaking change.
- Bound query cost. Clients can request deeply nested, expensive queries (the flip side of flexibility): defend with query depth limits, complexity analysis (cost per field, reject over-budget queries), and timeouts (see backpressure, rate-limiting). An unbounded GraphQL endpoint is a self-service denial-of-service; the schema must constrain what queries can cost.
- Design errors and nullability deliberately. GraphQL returns partial data with an errors array (a resolver can fail while others succeed): decide per field whether failure nullifies the field or propagates, and use the schema's nullability to express what can be absent (see null-handling, api-error-responses). The error model is subtler than REST's status codes; design it, do not inherit it by accident.
- Evolve additively, deprecate with the directive.
GraphQL evolves without versions: add fields and types
freely (clients request only what they use), deprecate
old fields with
@deprecatedand a reason, track usage, and remove once unused (see api-deprecation, api-change- management). This is a real advantage, but only if you monitor field usage before removing.
Boundaries
- GraphQL is not universally better than REST: REST wins for simple CRUD, cacheable public resources (HTTP caching is harder in GraphQL: see http-caching), file uploads/ downloads, and when clients do not need query flexibility. Choose per API, not by fashion (see rest-endpoint-design).
- The flexibility shifts complexity to the server (cost control, caching, N+1, auth per field): GraphQL is not less work, it is different work, concentrated in schema and resolver design.
- Field-level authorization is essential and easy to miss (a nested field can leak data the top-level query authorized: see authz-design); every resolver is a security boundary, not just the entry point.