Last updated
Documentation Output Formats
- HTML — hosted documentation site with search and navigation sidebar
- Markdown — for GitHub README or wiki pages (renders automatically)
- PDF — for offline reference and stakeholder sharing
- JSON — machine-readable format for custom documentation tooling
Tips for Well-Documented Schemas
- Add description strings to every type, field, and argument — they appear in generated docs and introspection
- Document what a field returns, not just its name (e.g., "The user's email address" not just "email")
- Document constraints in descriptions (e.g., "Minimum 8 characters", "Must be unique")
- Use
@deprecated(reason: "...")with a migration path before removing fields - Document error cases in mutation return types
- Keep descriptions concise — one or two sentences per field is usually enough
Examples
Example 1: Schema with Descriptions
Input SDL with description strings:
"""
Represents a user account in the system.
"""
type User {
"""The unique identifier for the user."""
id: ID!
"""The user's display name."""
name: String!
"""The user's email address. Must be unique."""
email: String! @unique
"""The user's assigned role."""
role: UserRole!
"""All posts created by this user."""
posts(
"""Maximum number of posts to return."""
first: Int = 10
"""Cursor for pagination."""
after: String
): PostConnection!
"""When the account was created."""
createdAt: DateTime!
}
Generated documentation output:
## User
Represents a user account in the system.
### Fields
| Field | Type | Required | Description |
|-----------|-----------------|----------|--------------------------------------|
| id | ID | ✅ Yes | The unique identifier for the user. |
| name | String | ✅ Yes | The user's display name. |
| email | String | ✅ Yes | The user's email address. Must be unique. |
| role | UserRole | ✅ Yes | The user's assigned role. |
| posts | PostConnection | ✅ Yes | All posts created by this user. |
| createdAt | DateTime | ✅ Yes | When the account was created. |
### posts Arguments
| Argument | Type | Default | Description |
|----------|--------|---------|--------------------------------|
| first | Int | 10 | Maximum number of posts to return. |
| after | String | — | Cursor for pagination. |
Example 2: Query Documentation
Input SDL:
type Query {
"""Fetch a single user by ID."""
user(
"""The user's unique identifier."""
id: ID!
): User
"""List all users with optional filtering."""
users(
"""Filter by role."""
role: UserRole
"""Maximum results to return."""
first: Int = 20
"""Pagination cursor."""
after: String
): UserConnection!
"""Search users by name or email."""
searchUsers(
"""Search query string."""
query: String!
): [User!]!
}
Generated documentation:
## Queries
### user
Fetch a single user by ID.
Arguments:
id (ID!) — The user's unique identifier. Required.
Returns: User (nullable)
Example:
query GetUser($id: ID!) {
user(id: $id) {
id
name
email
role
}
}
### users
List all users with optional filtering.
Arguments:
role (UserRole) — Filter by role. Optional.
first (Int, default: 20) — Maximum results to return.
after (String) — Pagination cursor. Optional.
Returns: UserConnection! (non-null)
### searchUsers
Search users by name or email.
Arguments:
query (String!) — Search query string. Required.
Returns: [User!]! (non-null list of non-null User)
Example 3: Mutation Documentation
## Mutations
### createUser
Create a new user account.
Arguments:
input (CreateUserInput!) — User creation data. Required.
Returns: CreateUserPayload!
Example:
mutation CreateUser($input: CreateUserInput!) {
createUser(input: $input) {
user {
id
name
email
}
errors {
field
message
}
}
}
Variables:
{
"input": {
"name": "Alice",
"email": "alice@example.com",
"role": "EDITOR"
}
}
### updateUser
Update an existing user's information.
Arguments:
id (ID!) — The user to update. Required.
input (UpdateUserInput!) — Fields to update. Required.
Returns: UpdateUserPayload!
### deleteUser
Delete a user account.
Arguments:
id (ID!) — The user to delete. Required.
Returns: DeleteUserPayload!
⚠️ This operation is irreversible.