Best practices for documenting GraphQL schemas with SDL
Diagnostic Overview: CI/CD & Codegen Failures
CI pipelines consistently fail at the schema:validate stage, emitting GraphQLError: Field 'userPreferences' lacks description metadata or ContractMismatch: Generated TypeScript client omits nullable fields due to missing SDL docstrings. These validation gates trigger downstream codegen breaks in tools like @graphql-codegen/cli and Apollo CLI. The resulting incomplete type definitions propagate to frontend builds as TS2339: Property does not exist errors, breaking automated contract assertions and halting deployment pipelines.
Root Cause Analysis: SDL AST & Validation Gaps
GraphQL Schema Definition Language (SDL) documentation relies exclusively on triple-quoted strings ("""...""") or @deprecated directives. During rapid iteration cycles, developers frequently strip these annotations, leaving the AST description property null. Strict contract validation frameworks parse the SDL AST for description nodes; when absent, validation gates reject the schema, breaking downstream API Contract Fundamentals & Tool Selection workflows.
Unlike OpenAPI, GraphQL SDL lacks a centralized metadata block. Governance rules must be embedded directly into type and field definitions. Without explicit documentation, schema diffing tools cannot accurately track breaking changes or generate consumer-facing contracts, causing silent type drift and runtime mismatches.
Step-by-Step Resolution
Follow this diagnostic sequence to restore validation gates and stabilize codegen outputs.
1. Audit the SDL AST for Missing Descriptions
Use the graphql library’s validateSchema and printSchema utilities to identify nodes where description is null or undefined. Run a targeted AST traversal to isolate undocumented fields before applying structural fixes.
2. Enforce Mandatory Triple-Quoted Docstrings
Apply """...""" annotations to all type, input, enum, and field definitions. SDL parsers strictly require this syntax for documentation nodes. Inline comments (#) are stripped during parsing and do not populate the AST description property.
3. Inject a Custom ValidationRule into CI Block undocumented fields at the validation stage by injecting a custom rule into your CI script. This ensures zero-tolerance enforcement before codegen runs.
const { ValidationContext, GraphQLError } = require('graphql');
function RequireDescriptionsRule(context) {
return {
FieldDefinition(node) {
if (!node.description) {
context.reportError(new GraphQLError(`Field '${node.name.value}' requires SDL documentation.`));
}
return false;
}
};
}
module.exports = RequireDescriptionsRule;
4. Configure Codegen for Strict JSDoc/TSDoc Mapping
Update codegen.yml to explicitly map SDL description nodes to generated TypeScript comments. This prevents type omission and enforces strict output formatting.
schema: './schema.graphql'
generates:
./src/types/graphql.ts:
config:
description: 'JSDoc'
skipTypename: true
add:
- '/* Auto-generated from validated SDL with enforced documentation */'
plugins:
- typescript
- typescript-operations
5. Re-run Pipeline & Verify Outputs
Execute npm run codegen && npm run validate:contract. Confirm zero TS2339 or GraphQLError outputs. Verify that the generated graphql.ts file contains complete nullable field definitions and JSDoc annotations matching the SDL source.
Prevention & Schema Governance
Enforce pre-commit hooks using graphql-schema-linter with a custom require-description rule that fails on git push. Integrate @graphql-inspector/cli diffing into PR checks to block undocumented schema mutations before they reach staging. Standardize SDL annotation templates in your developer handbook and align contract governance with broader REST vs GraphQL vs gRPC Contract Strategies to maintain consistent metadata requirements across polyglot API ecosystems. Schedule quarterly schema audits to prune deprecated fields and validate documentation coverage against active consumer queries.