💻 Développement

dev-rest-api-designer

Conception d'APIs REST conformes aux standards et bonnes pratiques.

⚡ Installation & lancement en 1 commande

Copiez-collez dans votre terminal : le skill s'installe dans ~/.claude/skills et Claude Code se lance directement dessus.

macOS / Linux
curl -fsSL https://raw.githubusercontent.com/khalilbenaz/claude-skills-collection/main/install.sh | sh -s -- dev-rest-api-designer --launch
Windows (PowerShell)
iex "& { $(iwr -useb https://raw.githubusercontent.com/khalilbenaz/claude-skills-collection/main/install.ps1) } dev-rest-api-designer -Launch"

🚀 Déjà installé ?

claude "/dev-rest-api-designer"

Ou tapez /dev-rest-api-designer dans une session Claude Code, ou décrivez simplement votre besoin — le skill se déclenche automatiquement via le skill-router.

🔑 Déclencheurs automatiques

Le skill s'active automatiquement quand votre demande contient :

API RESTconcevoir une APIendpointsREST designresource namingHTTP methodsAPI versioningpagination

📦 Installation manuelle

git clone https://github.com/khalilbenaz/claude-skills-collection.git cp -r claude-skills-collection/skills/dev-rest-api-designer ~/.claude/skills/

Payload du plugin : skills/dev-rest-api-designer · source éditable : dev-skills/rest-api-designer

đź“– Manuel

REST API Designer

Workflow

1. Identifier les ressources et relations

Partir du domaine métier, pas des tables. Chaque entité devient une collection.

GET  /users                    # collection
GET  /users/{id}               # singleton
GET  /users/{id}/orders        # relation imbriquée (max 2 niveaux)
GET  /orders/{id}/items/{itemId}

Règles de nommage :

2. Choisir les verbes HTTP et codes de statut

ActionVerbeSuccèsIdempotent
LireGET200Oui
CréerPOST201 + Location: /resource/{id}Non
Remplacer completPUT200 ou 204Oui
Mise à jour partiellePATCH200Non (en général)
SupprimerDELETE204Oui
Vérifier existenceHEAD200/404Oui

Codes essentiels à maîtriser :

3. Pagination, filtrage, tri

Cursor-based (préféré pour grandes collections, flux en temps réel) :

GET /events?cursor=eyJpZCI6MTAwfQ&limit=50
→ { "data": [...], "next_cursor": "eyJpZCI6MTUwfQ", "has_more": true }

Offset (plus simple, navigation par page) :

GET /products?page=3&size=25
→ { "data": [...], "total": 1240, "page": 3, "pages": 50 }

Critère de choix : cursor = performances + cohérence ; offset = flexibilité (aller page N directement).

Filtrage et tri :

GET /orders?status=pending&created_after=2026-01-01&sort=amount:desc,created_at:asc

4. Versioning — choisir sa stratégie

StratégieExemplePourContre
URL path/v2/usersVisibilité, cache HTTP natifPolluant sémantiquement
HeaderAccept: application/vnd.myapi.v2+jsonPropre, REST purMoins discoverable
Query param?api-version=2026-01Simple Ă  testerNon standard

Recommandation par défaut : URL path pour API publique, header pour API interne/partenaire.

Politique de dépréciation obligatoire :

Deprecation: true
Sunset: Sat, 01 Jan 2027 00:00:00 GMT
Link: <https://api.example.com/v3/users>; rel="successor-version"

5. Error handling — RFC 7807 Problem Details

HTTP/1.1 422 Unprocessable Entity
Content-Type: application/problem+json

{
  "type": "https://api.example.com/errors/validation-failed",
  "title": "Validation Failed",
  "status": 422,
  "detail": "Le champ 'email' est invalide.",
  "instance": "/users/register",
  "code": "VALIDATION_FAILED",
  "errors": [
    { "field": "email", "code": "INVALID_FORMAT", "message": "Format attendu : user@domain.tld" }
  ]
}

Toujours inclure :

6. Authentification et autorisation

# JWT Bearer (API publique)
Authorization: Bearer eyJhbGciOiJSUzI1NiJ9...

# API Key (intégrations M2M simples)
X-API-Key: sk_live_xxxxxxxxxxxx

# OAuth2 Client Credentials (services internes)
POST /oauth/token
{ "grant_type": "client_credentials", "scope": "orders:read payments:write" }

Principes :

7. Documentation OpenAPI 3.1

Structure minimale viable :

openapi: 3.1.0
info:
  title: My API
  version: 2.0.0
paths:
  /users/{id}:
    get:
      summary: Récupérer un utilisateur
      parameters:
        - name: id
          in: path
          required: true
          schema: { type: string, format: uuid }
      responses:
        '200':
          content:
            application/json:
              schema: { $ref: '#/components/schemas/User' }
              example: { id: "550e8400-...", email: "user@example.com" }
        '404':
          content:
            application/problem+json:
              schema: { $ref: '#/components/schemas/ProblemDetail' }
components:
  schemas:
    User:
      type: object
      required: [id, email]
      properties:
        id: { type: string, format: uuid }
        email: { type: string, format: email }

Générer la spec avant le code (contract-first) avec Stoplight, Redocly ou directement dans le repo.

8. Idempotence et sécurité des opérations critiques

Pour les POST non-idempotents (paiement, création de commande) :

POST /payments
Idempotency-Key: a1b2c3d4-e5f6-...   # UUID généré côté client

→ Stocker la clé + résultat côté serveur pendant 24h
→ Même clé = même réponse, pas de double débit

Anti-patterns et pièges

Anti-patternProblèmeSolution
POST /getUsersVerbe dans l'URLGET /users
Retourner 200 avec { "error": true }Masque les erreurs aux proxies et clients HTTPUtiliser les codes HTTP corrects
Exposer l'ID incrémental de la DBEnumeration attack, couplage schemaUUID v4 ou ULID
Imbrication > 2 niveaux/a/{id}/b/{id}/c/{id} ingérableRessource plate + filtre : GET /c?b_id=x
Ignorer les IDs de corrélationDebugging impossible en prodX-Request-Id en entrée, retourné en réponse
Pas de rate limiting documentéClients en boucle infinie sur 429Header X-RateLimit-Limit, X-RateLimit-Remaining, Retry-After
Réponses différentes pour le même endpointGET /users renvoie tantôt array, tantôt objetToujours { "data": [...] } enveloppé
DELETE qui renvoie 200 + bodyNon cohérent avec l'idempotence204 No Content

Bonnes pratiques 2026