awesome-ai-prompts

GraphQL API design

One prompt from the awesome-ai-prompts catalog, ready to paste into your AI coding agent.

Copy-paste the block below into any AI coding agent to design a GraphQL schema that scales past the demo: batching, field-level authorization, bounded complexity, and resolvers that do not turn one query into fifty queries.

Keywords: graphql, schema, resolver, n plus 1, dataloader, query complexity, authz

Design the GraphQL API for `[feature or domain]` in this repository. The rule:
**the client drives the query shape, so the server must own the cost**. Design
schema-first, authorize per field, and make an expensive query fail on purpose
rather than in production.

## Steps

1. **Model from the domain, not the tables** - Write the SDL for the types this feature exposes, name fields for what the client needs, and keep mutations coarse-grained. Mark nullability deliberately: a non-null field that throws nulls out to its parent and can blank an entire response.
2. **Fix connection conventions first** - One pagination style everywhere, Relay cursor or a documented offset/limit. A bare `[Type]` with no arguments invites unbounded queries, so every list field takes `first`/`last` with a documented maximum.
3. **Plan N+1 before writing resolvers** - Mark every nested selection that crosses an object boundary, for example `Query.posts -> Post.author`. Each is a second query unless batched. Choose the strategy per boundary (request-scoped DataLoader, a joined SQL query) and write down why.
4. **Authorize per field, not per query** - Enforce access where the data resolves, since a top-level guard does not protect a nested field. Decide and document what a field does for a viewer without access: hide it, return null, or raise a typed error, and be consistent.
5. **Bound and standardize** - Set depth and field-count limits from what the app actually needs, not from the example query. Give errors a stable shape: a machine-readable `code`, a user-safe message, and a request id. State the evolution rule, additive by default, `@deprecated(reason:)`, with a sunset process.
6. **Verify against real queries** - Run a deep nested query, an unbounded list, a field the viewer must not see, and a mutation that fails halfway. Count the queries each one issues and show the numbers.

## Verification

- [ ] The SDL is pasted, and no database column or table shape is exposed as the schema.
- [ ] Every list field takes a maximum, so no query is unbounded.
- [ ] The batching strategy is written per nested boundary, and any unresolved N+1 is called out rather than shipped.
- [ ] Depth and complexity limits are set to concrete numbers, not left at a default.
- [ ] The four step 6 queries ran, with the measured query count for each shown.
- [ ] The unauthorized-field case returns the documented behavior instead of the data.

## Rules

- Never expose a database column or table shape as the schema. The schema is a
  contract, not a mirror.
- Never resolve a nested object field with a query per parent. If the N+1 is
  unresolved, say so in the design rather than shipping it.
- Never return an unbounded list. Every list field takes a maximum.
- Never rely on a top-level auth check to protect a nested field.
- Never ship without the depth and complexity limits set to concrete numbers.

More core-coding prompts