Pourquoi ne pas renvoyer du JSON « maison » à chaque fois ?
Sans convention, chaque endpoint invente ses clés (error, message, errors[]…).
Les SDK et les intégrations deviennent fragiles. Problem Details donne un contrat minimal reconnu par
les outils et les humains.
Champs utiles en pratique
-
type: URI (souvent sous votre domaine) identifiant la classe d’erreur — stable dans le temps. title: libellé court, lisible ; peut être localisé si vous versionnez l’API.status: redondance explicite avec le code HTTP (422, 404, 409…).-
detail: message contextuel (éviter les données sensibles ; préférer un identifiant de corrélation). instance: URI de la requête fautive ou id de trace pour le support.
Exemple de corps 422 (validation)
{
"type": "https://api.example.com/problems/validation-failed",
"title": "Validation Failed",
"status": 422,
"detail": "One or more fields are invalid.",
"instance": "/v1/orders",
"errors": [
{ "field": "email", "code": "invalid_format" }
]
}
Le tableau errors est une extension courante (non obligatoire dans la RFC) : documentez-la
dans votre spec OpenAPI.
Symfony : JsonResponse typée
use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Response;$body = [ ‘type’ => ‘https://api.example.com/problems/not-found’, ‘title’ => ‘Resource Not Found’, ‘status’ => Response::HTTP_NOT_FOUND, ‘detail’ => ‘No order matches this id.’, ‘instance’ => $request->getRequestUri(), ];
return new JsonResponse( $body, Response::HTTP_NOT_FOUND, [‘Content-Type’ => ‘application/problem+json’] );
Listener d’exception
Centralisez la traduction ValidationFailedException → 422, EntityNotFound → 404, erreurs
métier → 409, etc. Gardez un seul format de sortie pour toute l’API.
FAQ
Faut-il toujours utiliser application/problem+json ?
Recommandé pour les erreurs ; pour les réponses 2xx vous gardez votre schéma métier. L’important est la cohérence des erreurs sur tout le périmètre API.
Et les erreurs Symfony Validator en tableau ?
Normalisez-les dans une extension (violations ou errors) avec codes stables, pas seulement
les messages traduits — les clients s’appuient sur les codes.