- Home
- Skills
- APIs & Backend
- GraphQL API Contract and Schema Design
GraphQL API Contract and Schema Design
Designs GraphQL schemas: type definitions, query depth/complexity bounds, DataLoader N+1 mitigation, and Relay pagination.
$5
Works with the AI Agents you already use
GraphQL API Contract and Schema Design
Example session with this skill installed
Design the GraphQL schema and query protection contract for our Creator Marketplace Storefront API.
- Subject: marketplace-graphql-api v2.0 (run-id: marketplace-gql-001) federating Creator Profiles, Digital Assets, and Customer Reviews.
- Deciders: Lead API Standards Architect (Sarah Chen) and Platform Performance Lead (Marcus Vance).
- Traffic & Scale: Peak 1,600 GraphQL queries/sec; p95 latency budget <= 150 ms; PostgreSQL database backing 250,000 digital products.
- Tension: Frontend web team requested unrestricted nested queries (author -> products -> reviews -> author...) without depth or complexity bounds to simplify mobile component trees; Marcus Vance warns that recursive cyclic queries cause catastrophic database Denial of Service (incident INC-3904 where a 9-level nested query locked RDS CPU at 100% for 22 minutes), mandating a strict query depth ceiling (max depth 6), query complexity cost analysis (max cost 250 points per query), mandatory DataLoader batching to eliminate N+1 queries, and Relay-style cursor connections (first, after, pageInfo) for all paginated lists.
Write the GraphQL schema contract under docs/.
- Read your context and instructions
- Compiled the graphql api contract
Wrote docs/architecture/tasks/marketplace-gql-001/graphql-api-design/graphql-schema-contract.md. Complete GraphQL schema contract specifying GraphQL SDL, query depth ceiling (max 6), complexity score bounding (max 250), DataLoader N+1 batching, and Relay connection pagination.
---
skill: graphql-api-design
---
# GraphQL Schema Contract: Creator Marketplace Storefront [GQL-MKT-001]
## Summary
This specification establishes the enterprise GraphQL schema, resolver execution architecture, and query safety contract for `marketplace-graphql-api v2.0` under run ID `marketplace-gql-001`. It federates Creator Profiles, Digital Assets, and Customer Reviews across 250,000 products, sustaining 1,600 peak queries/second within a 150 ms p95 latency SLA. It decisively resolves the catastrophic database exhaustion exposed in incident INC-3904 (where a 9-level circular query triggered 100% database CPU lockup for 22 minutes) by rejecting unbounded nested queries. The contract mandates a strict query depth ceiling of 6, an algorithmic complexity cost ceiling of 250 points per query, batch-loading via DataLoader to eliminate N+1 queries, and the Relay Cursor Connections specification for collection pagination.
## Detailed Description
GraphQL's flexible client-driven querying invites severe server-side Denial of Service vulnerabilities when query depth and cardinality remain unconstrained. Without server-side depth and complexity validation, malicious or poorly drafted client queries execute exponential database queries through cyclic object graphs (e.g. `Creator -> Products -> Reviews -> Creator -> Products...`).
Incoming Client Query: query { creator(id: "c_12") { products(first: 20) { reviews { author { ... } } } } }
│
▼
[ GraphQL Ingress Engine / Apollo Server ]
├── 1. Syntax & Type Validation (GraphQL SDL)
├── 2. Query Depth Analysis (Ceiling: Max 6 Levels) ────► Exceeded: HTTP 400 (ERR_QUERY_TOO_DEEP)
├── 3. Complexity Cost Calculator (Ceiling: 250 Points) ─► Exceeded: HTTP 400 (ERR_COMPLEXITY_EXCEEDED)
│
▼
[ Resolver Execution Seam with DataLoader ]
├── CreatorResolver: Batches Creator IDs via CreatorLoader
├── ProductResolver: Batches Product IDs via ProductLoader
└── ReviewResolver: Single SQL IN (...) Query (Zero N+1)
│
▼
[ Relayed Response Payload (Latency p95 <= 110 ms) ]
### Criteria and weights
| Criterion | Why it matters here | Weight | Source of the weight |
|---|---|---|---|
| Query DoS Defense & Depth Bounding | Unbounded recursive queries lock database CPUs and cause platform-wide outages (INC-3904). | 0.40 | Marcus Vance (Performance Lead) |
| N+1 Resolver Batching & Index Efficiency | Fetching related reviews and authors must never execute O(N) individual SELECT queries. | 0.30 | Database Reliability Standard |
| Client Pagination Predictability | Collection pagination must adhere to stable Relay cursor standards, avoiding deep-offset scans. | 0.15 | Sarah Chen (API Standards) |
| Standardized Partial Error Taxonomy | Graph execution failures must differentiate field-level validation from unauthenticated tokens. | 0.15 | Client Engineering Guild |
### Comparison
| Query Protection Candidate | Depth Control Model | Complexity Analysis | Database Load Profile | Evaluation |
|---|---|---|---|---|
| Option A: Unconstrained Native GraphQL | None (Client requests arbitrary depth) | None | Exponential O(N^K) database queries | Rejected: Recreates INC-3904 database CPU collapse. |
| Option B: Execution Timeout Only (5s) | Thread timeout kill switch | None | High initial CPU spike before socket kill | Rejected: Sits on DB connections for 5s before failing; burns capacity. |
| Option C: Static Depth + Complexity Cost (Chosen) | AST inspection (Max Depth: 6) | Field score sum (Max Cost: 250) | Constant O(1) batched queries via DataLoader | Selected: Rejects abusive queries before resolver execution in < 3 ms. |
### Result
Option C is selected. Pre-execution AST validation rejects deeply nested or computationally expensive queries before database execution.
---
### Required Mechanisms
#### 1. GraphQL SDL Schema Definition [MC-SDL-01]
```graphql
```bash
type Query {
creator(id: ID!): Creator
product(id: ID!): Product
marketplaceFeed(first: Int = 20, after: String): ProductConnection!
}
type Creator {
id: ID!
handle: String!
displayName: String!
products(first: Int = 10, after: String): ProductConnection!
}
type Product {
id: ID!
slug: String!
title: String!
priceCents: Int!
creator: Creator!
reviews(first: Int = 10, after: String): ReviewConnection!
}
type Review {
id: ID!
rating: Int!
comment: String
author: User!
createdAt: String!
}
type User {
id: ID!
username: String!
}
type PageInfo {
hasNextPage: Boolean!
hasPreviousPage: Boolean!
startCursor: String
endCursor: String
}
type ProductConnection {
edges: [ProductEdge!]!
pageInfo: PageInfo!
totalCount: Int!
}
type ProductEdge {
cursor: String!
node: Product!
}
type ReviewConnection {
edges: [ReviewEdge!]!
pageInfo: PageInfo!
totalCount: Int!
}
type ReviewEdge {
cursor: String!
node: Review!
}
#### 2. Query Complexity & Depth Limiting Defenses [MC-CD-01]
- **Depth Limiting Rule**: Query AST depth must not exceed 6 levels.
- Calculation: Root `Query` = Level 0; `creator` = Level 1; `products` = Level 2; `edges` = Level 3; `node` = Level 4; `reviews` = Level 5; `author` = Level 6.
- Queries requesting Level 7 are rejected before execution with error code `ERR_QUERY_DEPTH_EXCEEDED`.
- **Complexity Cost Rules**:
- Scalar fields (`id`, `title`, `priceCents`): **1 point**.
- Object fields (`creator`, `product`): **2 points**.
- Connections (`products(first: N)`): Multiplier formula:
$$\text{Cost} = 2 + (N \times \text{ChildFieldCosts})$$
- Max Permitted Query Cost: **250 points**. Queries exceeding 250 points terminate immediately with `ERR_COMPLEXITY_EXCEEDED`.
#### 3. DataLoader & N+1 Prevention Strategy [MC-DL-01]
Resolvers are forbidden from issuing direct database queries. All relational lookups use batch DataLoaders:
- `ProductByCreatorLoader`: Consolidates creator IDs across the event loop turn and issues single query:
`SELECT * FROM products WHERE creator_id IN ($1, $2, ...) ORDER BY created_at DESC;`
- `ReviewByProductLoader`: Batches product IDs and executes single query returning partitioned results.
#### 4. Error Formatting & Partial Failure Contracts [MC-EF-01]
Errors adhere to GraphQL specification with typed extensions:
```json
{
"errors": [
{
"message": "Query depth of 7 exceeds the maximum allowed depth of 6.",
"locations": [{ "line": 4, "column": 7 }],
"path": ["creator", "products", "edges", "node", "reviews", "edges", "node", "author"],
"extensions": {
"code": "ERR_QUERY_DEPTH_EXCEEDED",
"currentDepth": 7,
"maxDepth": 6
}
}
],
"data": null
}
Invariants and Contracts
Query Depth Ceiling Invariant [INV-GQL-01]
The GraphQL engine must enforce an immutable depth ceiling of 6 levels. Queries exceeding
6 levels must be aborted during AST parsing prior to resolver invocation.
Complexity Cost Ceiling Invariant [INV-GQL-02]
The calculated complexity cost of any query must not exceed 250 points. Requests specifying
unbounded `first` arguments or deep collections must be rejected with HTTP 400.
DataLoader Resolution Mandate [INV-GQL-03]
Resolvers for relational association fields (`products`, `reviews`, `creator`) must resolve
exclusively through registered DataLoaders. Inline SQL calls in resolver functions are prohibited.
Explicit Unknowns
- Memory footprint of DataLoader caches when individual client queries request 100 items across multiple connections (G-1).
- Apollo Federation subgraph schema composition latency during continuous CI/CD deployments (G-2).
Traceability
| Claim | Classification | Source | Freshness |
|---|---|---|---|
| 250,000 digital products catalog | provided | Catalog scale intake | Current |
| Peak 1,600 queries/sec | provided | Traffic profile | Current |
| Latency budget p95 <= 150 ms | provided | SLA constraint | Current |
| Incident INC-3904 9-level cyclic CPU lock | provided | Post-mortem evidence | Historical |
| Max depth 6, max complexity 250 points | decided | Marcus Vance & Sarah Chen | 2026-09-15 |
| Mandatory DataLoader batching | decided | Architectural invariant INV-GQL-03 | 2026-09-15 |
Verification
No validator was supplied, so no command was run.
Reviewer self-check against GraphQL schema contracts:
- Schema Soundness: PASS. Relay connection pagination and strict GraphQL SDL specified.
- DoS Protection: PASS. Hard depth ceiling (6) and complexity budget (250) prevent CPU lockups.
- N+1 Elimination: PASS. DataLoader batching mandates single SQL statements per entity tier.
- Error Transparency: PASS. Standard GraphQL error response includes typed extension codes.
Open Decisions
DEC-GQL-01: Sarah Chen to determine whether persisted queries (Automatic Persisted Queries / APQ) should be mandatory for all public production traffic (Owner: Sarah Chen).
Next steps
- Sarah Chen reviews GraphQL schema SDL with mobile engineering leads.
- Platform team configures
graphql-depth-limitandgraphql-validation-complexityplugins in Apollo Server. - Conduct staging stress test verifying DataLoader batching under 1,600 queries/sec load.
Connects securely to your tools. The creator never sees your data.
About this skill
What it does
This skill maps authoritative consumer capabilities and domain/API semantics into a GraphQL schema contract: graph identities, type/field/argument/input meanings, root operations, null/list/error behavior, authorization references, collection seams and evolution.
Use it when
Use when accepted consumer operations and domain identities/relationships need a precise GraphQL-facing graph contract.
For example: “One mobile query brought down the API. It asked for customers, their orders, each order's items, and each item's supplier, four levels deep, for 200 customers.”
What you get
- GraphQL Schema Definition
Written as Markdown to <your output folder>/architecture/tasks/<run-id>/graphql-api-design/.
What it will not do
Do not use for domain/data modeling, general API/federation design, resolver/client implementation, query optimization, pagination/filter/auth policy, subscription transport or generation.
How it works
- Check GraphQL earns its cost here.
- Design the graph from the domain, not from the tables.
- Bound query cost before exposure.
- Solve N+1 in the schema design, not only with a loader.
- Enforce authorisation per field and per node, not at the query root.
- Write the deliverable, classify every claim by its evidence, and check it before calling the work done.
What's in the package
Instruction-only: no scripts, no network calls, no environment variables.
- LICENSE.txt
- SKILL.md
- agents/openai.yaml
- assets/output-template-task.md
- references/domain-rules.md
- references/operating-rules.md
- references/output-contract.md
Find more skills like this on the Claude Skills Marketplace, the Codex Skills Marketplace and the Gemini Skills Marketplace, or browse Claude Skills for APIs & Backend.
Do not use for domain/data modeling, general API/federation design, resolver/client implementation, query optimization, pagination/filter/auth policy, subscription transport or generation.
How to use
- 1
Connect your agent to the Agensi MCP
Copy the prompt and paste it into Claude, ChatGPT, Cursor or any agent that supports MCP. It sets up the connection for you. Manual setup
- 2
Sign in to Agensi
Your agent shows a sign-in link. Sign in and click Allow.
- 3
Ask for what you need
Your agent loads this skill and uses it on your task. It always asks before buying a skill.
Reviews
No reviews yet
Be one of the first to try it. Every listed skill goes through the trust checks below.
Security scanned
Checked by our 8-point scan before listing
Fresh listing
Recently published to Agensi
Money-back guarantee
Doesn't do what its page promises? You get your money back.
Trust & safety
Security scan
Security scan passed 1 month ago
Permissions
Reads the files you point it at and writes Markdown under the output folder you name. No network access, no environment variables, and no bundled scripts.