dev-rest-api-designer
Conception d'APIs REST conformes aux standards et bonnes pratiques. Se déclenche avec "API REST", "concevoir une API", "endpoints", "REST design", "resource naming", "HTTP methods", "API versioning", "pagination". Also triggers on "design a REST API", "endpoint naming", "HTTP status codes", "pagination design".
Works with
---
name: dev-rest-api-designer
description: Conception d'APIs REST conformes aux standards et bonnes pratiques. Se déclenche avec "API REST", "concevoir une API", "endpoints", "REST design", "resource naming", "HTTP methods", "API versioning", "pagination". Also triggers on "design a REST API", "endpoint naming", "HTTP status codes", "pagination design".
license: MIT
---
# 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 :
- **Pluriel** toujours : `/orders`, pas `/order`
- **kebab-case** : `/payment-methods`, pas `/paymentMethods`
- **Noms, pas verbes** : `/users/{id}/activate` avec `POST` — pas `GET /activateUser`
### 2. Choisir les verbes HTTP et codes de statut
| Action | Verbe | Succès | Idempotent |
|--------|-------|--------|------------|
| Lire | GET | 200 | Oui |
| Créer | POST | 201 + `Location: /resource/{id}` | Non |
| Remplacer complet | PUT | 200 ou 204 | Oui |
| Mise à jour partielle | PATCH | 200 | Non (en général) |
| Supprimer | DELETE | 204 | Oui |
| Vérifier existence | HEAD | 200/404 | Oui |
Codes essentiels à maîtriser :
- `400` = requête malformée (validation côté serveur)
- `401` = non authentifié
- `403` = authentifié mais interdit
- `404` = ressource inexistante
- `409` = conflit (doublon, état incompatible)
- `422` = entité non traitable (logique métier, pas format)
- `429` = rate limit atteint (header `Retry-After`)
### 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égie | Exemple | Pour | Contre |
|-----------|---------|------|--------|
| **URL path** | `/v2/users` | Visibilité, cache HTTP natif | Polluant sémantiquement |
| **Header** | `Accept: application/vnd.myapi.v2+json` | Propre, REST pur | Moins discoverable |
| **Query param** | `?api-version=2026-01` | Simple à tester | Non 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
```json
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 :
- `code` machine-readable (snake_upper) pour le traitement programmatique client
- `errors[]` pour les erreurs de validation multiples
- `instance` = URI de la requête ayant échoué
### 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 :
- Valider le scope au niveau endpoint (`orders:read`) ET au niveau ressource (l'utilisateur peut-il accéder à cette commande ?)
- Tokens JWT : durée courte (15 min), refresh token rotatif
- Ne jamais exposer de données sensibles dans un `GET` avec query params (loggés partout)
### 7. Documentation OpenAPI 3.1
Structure minimale viable :
```yaml
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-pattern | Problème | Solution |
|---|---|---|
| `POST /getUsers` | Verbe dans l'URL | `GET /users` |
| Retourner 200 avec `{ "error": true }` | Masque les erreurs aux proxies et clients HTTP | Utiliser les codes HTTP corrects |
| Exposer l'ID incrémental de la DB | Enumeration attack, couplage schema | UUID v4 ou ULID |
| Imbrication > 2 niveaux | `/a/{id}/b/{id}/c/{id}` ingérable | Ressource plate + filtre : `GET /c?b_id=x` |
| Ignorer les IDs de corrélation | Debugging impossible en prod | `X-Request-Id` en entrée, retourné en réponse |
| Pas de rate limiting documenté | Clients en boucle infinie sur 429 | Header `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `Retry-After` |
| Réponses différentes pour le même endpoint | `GET /users` renvoie tantôt array, tantôt objet | Toujours `{ "data": [...] }` enveloppé |
| `DELETE` qui renvoie 200 + body | Non cohérent avec l'idempotence | 204 No Content |
## Bonnes pratiques 2026
- **Contract-first** : spec OpenAPI committée dans le repo, générée avant l'implémentation, testée avec Schemathesis ou Dredd
- **Liens HATEOAS légers** : ajouter `_links.self` et `_links.next` dans les collections sans surcharger avec HAL complet si inutile
- **Versionner les breaking changes seulement** : ajouter un champ est non-breaking ; en retirer, changer un type ou renommer = breaking
- **`ETag` + `If-None-Match`** pour les GETs fréquents (réduction bande passante, cache côté client)
- **`PATCH` avec JSON Merge Patch** (RFC 7396) plutôt que JSON Patch (RFC 6902) pour la majorité des cas : plus lisible, moins complexe
- **Documenter les SLAs dans l'OpenAPI** : `x-rate-limit`, `x-response-time-p99` dans l'extension `info`
- **Tester la surface d'attaque** : fuzzing avec Schemathesis dès la CI, OWASP API Security Top 10 (2023) comme checklist de review
## Communication Rules — MANDATORY
- Ultra-concise. No filler, no preamble, no pleasantries.
- Never say "happy to help", "sure!", "great question", "let me", or similar.
- Tool first, talk second. Act before explaining.
- Result first. Lead with outcome, not process.
- Stop when done. No summary, no recap, no trailing commentary.
- No politeness wrappers. Direct and blunt.
- Minimum words. If one word works, do not use ten.
- No unsolicited explanations.
- No emoji unless asked.More API Design skills
lark-event
larksuite/cli
Lark/Feishu real-time event listening / subscribing / consuming: stream events as NDJSON via `lark-cli event consume <EventKey>` (covers IM messages/reactions/chat changes, Approval status changes, Task updates, VC meeting started/joined/ended, Minutes generated, Whiteboard updated, etc.). Use for Lark bots, real-time message processing, long-running subscribers, streaming webhook/push handlers. Supports `--max-events` / `--timeout` bounded runs and a stderr ready-marker contract — designed for AI agents running as subprocesses.
lark-contact
larksuite/cli
飞书 / Lark 通讯录:按姓名 / 邮箱解析成 open_id,或按 open_id 反查姓名 / 部门 / 邮箱 / 联系方式 / 个人状态 / 签名,以及按关键词搜索当前用户可见的机器人 / 智能体(agent)。当用户提到一个名字要下一步发消息 / 排日程,或拿到 open_id 想查具体信息时使用。不负责部门树遍历、按部门列员工、组织架构图,这类需求走原生 OpenAPI。
lark-openapi-explorer
larksuite/cli
飞书/Lark 原生 OpenAPI 探索:从官方文档库中挖掘未经 CLI 封装的原生 OpenAPI 接口。当用户的需求无法被现有 lark-* skill 或 lark-cli 已注册命令满足,需要查找并调用原生飞书 OpenAPI 时使用。

