| name | api-documentation |
| description | API documentation pattern library — OpenAPI 3.1 specifications (the lingua franca of REST API description), Swagger UI / Redoc / Scalar / Stoplight Elements (interactive doc renderers), Postman + Postman Collections (request collections, environments, automated testing, monitoring), Bruno (open-source Postman alternative with file-based collections), Insomnia (free API client with team workspaces), API documentation generators (FastAPI auto-generates OpenAPI, NestJS via @nestjs/swagger, tRPC via openapi-trpc, Hono via @hono/zod-openapi), schema-first vs code-first approaches, versioning strategies (URL versioning vs header versioning), example-driven docs, contract testing (Pact, Schemathesis), and developer portal best practices. Use when documenting a new REST or GraphQL API, choosing between schema-first and code-first, generating SDK clients, setting up an interactive API explorer, or creating a developer portal. Differentiates from generic API design skills by focusing on the documentation deliverable that makes APIs usable by external developers. |
API Documentation Patterns
Une API sans doc = une API inutilisable. Ce skill couvre les outils et patterns pour produire des docs interactives, à jour, et generative-friendly (AI agents qui consomment la spec).
1. OpenAPI 3.1 (le standard)
OpenAPI (anciennement Swagger) décrit une API REST en YAML ou JSON. Format universel consommé par des dizaines d'outils.
openapi: 3.1.0
info:
title: My API
version: 1.0.0
description: Public API for My Service
servers:
- url: https://api.example.com/v1
paths:
/products:
get:
summary: List products
operationId: listProducts
tags: [Products]
parameters:
- name: limit
in: query
schema: { type: integer, default: 10, maximum: 100 }
- name: cursor
in: query
schema: { type: string }
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/ProductList'
'401':
$ref: '#/components/responses/Unauthorized'
components:
schemas:
Product:
type: object
required: [id, name, price]
properties:
id: { type: string }
name: { type: string }
price: { type: number, format: decimal }
currency: { type: string, default: EUR }
ProductList:
type: object
properties:
items:
type: array
items: { $ref: '#/components/schemas/Product' }
nextCursor: { type: string, nullable: true }
responses:
Unauthorized:
description: Authentication required
content:
application/json:
schema:
type: object
properties:
error: { type: string }
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
security:
- bearerAuth: []
2. Schema-first vs Code-first
Schema-first
Écrire la spec OpenAPI avant d'implémenter, puis générer les types/clients à partir de la spec.
npx openapi-typescript openapi.yaml -o src/api-types.ts
npx openapi-typescript-codegen --input openapi.yaml --output src/api
Avantages : la doc est la source de vérité, contrats stables, frontend et backend peuvent travailler en parallèle.
Code-first
Écrire le code et auto-générer la spec OpenAPI à partir des annotations.
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI(title="My API", version="1.0.0")
class Product(BaseModel):
id: str
name: str
price: float
@app.get("/products", response_model=list[Product])
def list_products(limit: int = 10):
return [...]
import { ApiTags, ApiOperation, ApiResponse } from '@nestjs/swagger'
@ApiTags('Products')
@Controller('products')
export class ProductsController {
@Get()
@ApiOperation({ summary: 'List products' })
@ApiResponse({ status: 200, type: [Product] })
list(@Query('limit') limit: number = 10) {
}
}
import { OpenAPIHono, createRoute, z } from '@hono/zod-openapi'
const app = new OpenAPIHono()
const ProductSchema = z.object({
id: z.string(),
name: z.string(),
price: z.number(),
})
const route = createRoute({
method: 'get',
path: '/products',
responses: {
200: {
content: { 'application/json': { schema: z.array(ProductSchema) } },
description: 'List products',
},
},
})
app.openapi(route, (c) => {
return c.json([...])
})
app.doc('/openapi.json', { openapi: '3.1.0', info: { title: 'My API', version: '1.0.0' } })
Avantages : moins de duplication, types auto-générés.
Inconvénients : la spec dépend de l'implémentation, pas idéal pour le contract-driven.
3. Renderers interactifs
Swagger UI (le plus courant)
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://unpkg.com/swagger-ui-dist@5/swagger-ui.css" />
</head>
<body>
<div id="swagger-ui"></div>
<script src="https://unpkg.com/swagger-ui-dist@5/swagger-ui-bundle.js"></script>
<script>
SwaggerUIBundle({ url: '/openapi.json', dom_id: '#swagger-ui' })
</script>
</body>
</html>
Redoc (UI épurée, lecture-friendly)
<redoc spec-url="/openapi.json"></redoc>
<script src="https://cdn.redoc.ly/redoc/latest/bundles/redoc.standalone.js"></script>
Scalar (moderne, populaire en 2025)
<script id="api-reference" data-url="/openapi.json"></script>
<script src="https://cdn.jsdelivr.net/npm/@scalar/api-reference"></script>
Stoplight Elements (Stoplight design)
<elements-api apiDescriptionUrl="/openapi.json" router="hash" />
<script src="https://unpkg.com/@stoplight/elements/web-components.min.js"></script>
Recommandation : Scalar ou Redoc pour une expérience moderne. Swagger UI pour la familiarité.
4. Postman Collections
Postman = client API graphique + collections de requêtes versionnées.
{
"info": { "name": "My API", "schema": "..." },
"item": [
{
"name": "List products",
"request": {
"method": "GET",
"header": [{ "key": "Authorization", "value": "Bearer {{token}}" }],
"url": "{{baseUrl}}/products?limit=10"
},
"response": []
}
],
"variable": [
{ "key": "baseUrl", "value": "https://api.example.com" }
]
}
Postman supporte aussi :
- Environments (dev / staging / prod avec vars différentes)
- Tests (
pm.test('status 200', () => pm.response.to.have.status(200)))
- Monitors (run la collection toutes les N minutes)
- Newman (CLI runner pour CI)
npm install -g newman
newman run my-api.postman_collection.json -e prod.postman_environment.json
5. Bruno (alternative open-source à Postman)
brew install bruno
Bruno utilise des fichiers texte dans le repo (pas un cloud sync) :
# my-api/products/list.bru
meta {
name: List products
type: http
seq: 1
}
get {
url: {{baseUrl}}/products?limit=10
}
headers {
Authorization: Bearer {{token}}
}
tests {
test("status 200", function() {
expect(res.getStatus()).to.equal(200);
});
}
Avantages Bruno :
- Tout est dans le repo Git → versioning natif
- Pas de cloud sync, privacy
- Format texte → review en PR
6. SDK generation
À partir d'une spec OpenAPI, générer automatiquement des clients pour plusieurs langages :
npx stainless generate
npx @openapitools/openapi-generator-cli generate \
-i openapi.yaml \
-g typescript-fetch \
-o ./sdk-ts
npx @hey-api/openapi-ts -i openapi.yaml -o src/client
Use case : distribuer un SDK officiel à vos clients API, pour qu'ils n'aient pas à écrire les types eux-mêmes.
7. Versioning
URL versioning (recommandé)
https://api.example.com/v1/products
https://api.example.com/v2/products
Simple, visible, cache-friendly.
Header versioning
GET /products
Accept: application/vnd.example.v1+json
Plus pur en théorie, mais difficile à debug.
Query param versioning
GET /products?version=1
À éviter — pollue les URLs.
8. Contract testing (Pact, Schemathesis)
Pact (consumer-driven contracts)
Le consumer (frontend) écrit des tests qui spécifient ce qu'il attend du provider (backend). Les tests sont publiés dans un Pact Broker, et le provider lance ses propres tests pour vérifier qu'il respecte tous les contracts.
const provider = new Pact({ consumer: 'frontend', provider: 'api' })
await provider.addInteraction({
state: 'has 3 products',
uponReceiving: 'a request for products',
withRequest: { method: 'GET', path: '/products' },
willRespondWith: {
status: 200,
body: like({ items: eachLike({ id: 'p1', name: 'Product 1', price: 99 }) }),
},
})
Schemathesis (property-based testing depuis OpenAPI)
pip install schemathesis
schemathesis run https://api.example.com/openapi.json
Génère des cas de test automatiques basés sur la spec et lance les vraies requêtes contre l'API.
9. Developer portal
Au-delà de la doc OpenAPI, un developer portal complet inclut :
- Getting started guide (5-10 minutes pour faire le premier appel)
- Authentication guide (comment obtenir une clé API)
- Tutorials (use cases concrets)
- API reference (générée depuis OpenAPI)
- SDK downloads (par langage)
- Changelog (versions, breaking changes)
- Status page (uptime, incidents)
- Support (Discord, email, GitHub Discussions)
Solutions managed : ReadMe, Mintlify, Stoplight, Bump.
10. Anti-patterns
- Doc Markdown manuelle non synchronisée avec le code → drift garanti
- OpenAPI manuel sans validation → spec invalide
- Pas d'examples dans les schemas → impossible de comprendre le format
- Versionnage par "v2 quand on cassera tout" sans plan → migration brutale
- Pas de changelog → users surpris par les breaking changes
- SDK généré non testé → users qui se plaignent
- Postman collection cloud sync committée dans Git → conflits
- OpenAPI 2.0 (Swagger) au lieu de 3.1 → fonctionnalités manquantes
- Auth non documentée → support tickets
- Pas de rate limit documenté → users qui se prennent du 429 sans comprendre
Checklist
Quand déléguer
- API design (architecture) → agent
api-designer (dans atum-stack-backend)
- GraphQL → agent
graphql-expert
- Backend implementation → agents stack-backend
- Authentication → skill
auth-providers (dans atum-stack-web)
- Rate limiting → skill
redis-patterns ou platform-specific (Cloudflare)
Ressources