Jaką strukturę powinna mieć odpowiedź API
Podsumowanie: Nagie obiekty są czyste, dopóki nie potrzebujesz metadanych; pełne koperty są bezpieczne, ale gadatliwe. W większości projektów użyj statusu HTTP dla wyników i stabilnej koperty dla danych.

Najważniejsze: wyrażaj wyniki kodami statusu 4xx/5xx, nieś ładunek w { "data": ..., "meta": ... } i przełączaj się na kopertę error przy porażce; to wystarczy dla wewnętrznych API, a tylko publiczne platformy z wieloma integratorami potrzebują JSON:API lub OpenAPI.
Najpierw wyklucz najgorszą opcję: zawsze zwracanie 200 z wynikiem w polu code.
Trzy kształty
A. Nagi obiekt
{ "id": 1, "name": "demo", "price": 99 }
Czyste, a semantyka HTTP robi swoją pracę (404 to 404). Ale w momencie, gdy potrzebujesz paginacji, ostrzeżeń lub id śledzenia, nie ma gdzie ich umieścić bez zmiany kontraktu.
B. Stabilna koperta
{
"data": { "id": 1, "name": "demo" },
"meta": { "requestId": "abc", "took": 12 }
}
Ładunek i metadane żyją osobno, więc nowe metadane nigdy nie zmieniają kształtu data. Kosztuje jedną warstwę zagnieżdżenia.
C. Koperta na wszystko (unikać)
{ "code": 0, "message": "success", "data": {...} }
Kształt nie jest grzechem; grzeszy praktyka. Status 200 dla każdego wyniku oznacza, że CDN-y, bramy, circuit breakery, polityki ponowień i dashboardy widzą sukces. Wtedy każdy alert potrzebuje niestandardowego parsowania.
Zalecenie
Status HTTP dla wyniku, koperta dla ładunku.
{
"data": { "id": 1, "name": "demo" },
"meta": { "requestId": "req_8f2a", "took": 12 }
}
{
"error": {
"code": "ORDER_NOT_FOUND",
"message": "Order does not exist or was deleted",
"details": [{ "field": "id", "issue": "not_found" }]
},
"meta": { "requestId": "req_8f2a" }
}
Status 4xx lub 5xx; code stabilny i czytelny maszynowo; message dla ludzi; details dla błędów pól formularza.
Twarde reguły
- Punkty końcowe list muszą nieść metadane paginacji. Bez
totallub kursora nie ma pagera. - Puste listy zwracają
[], nigdynull.null.mapto powracająca awaria. - Znaczniki czasu w ISO 8601 z przesunięciem. Zobacz jaki format znaczników czasu.
- Jedna konwencja nazewnictwa.
snake_caselubcamelCase, konwertowane raz na granicy. - Pieniądze jako całkowite jednostki pomocnicze lub łańcuchy.
99.99nie jest dokładne w binarnym zmiennoprzecinkowym. - Nie myl
nullz brakiem pola. Zobacznullczy pominięcie pola.
Kiedy przyjąć specyfikację
- Publiczne platformy z wieloma integratorami: JSON:API lub OpenAPI plus współdzielona koperta
- Wewnętrzne API jednego zespołu: powyższa koperta wystarczy
- Silne kontrakty: Schema najpierw, struktury generowane z niego
Specyfikacje oszczędzają dyskusji i kosztują onboarding. Dla pięcioosobowego zespołu JSON:API jest zwykle pracą ujemną.
FAQ
Jak wybrać między nagim obiektem a kopertą?
Użyj koperty, gdy potrzebujesz paginacji, ostrzeżeń lub requestId, aby meta mogło rosnąć bez zmiany kształtu data. Zwracaj nagi obiekt tylko wtedy, gdy nie potrzebujesz metadanych i akceptujesz, że dodanie pól później zmieni kontrakt.
Dlaczego API nigdy nie powinno zwracać 200 dla każdego wyniku?
CDN-y, bramy, circuit breakery, polityki ponowień i dashboardy czytają status HTTP, aby zdecydować, czy cache’ować, ponowić czy alertować. Przy 200 wszędzie traktują porażki jako sukcesy, a każdy alert wymaga niestandardowego parsowania kodu biznesowego.
Czy punkty końcowe list powinny nieść metadane paginacji?
Tak. Bez total lub kursora nie ma pagera, a puste listy muszą zwracać [], a nie null, inaczej .map we frontendzie się psuje.