JSON Toolkit

Welche Struktur sollte eine API-Antwort haben

Fazit: Nackte Objekte sind sauber, bis man Metadaten braucht; volle Hüllen sind sicher, aber geschwätzig. Für die meisten Projekte HTTP-Status für Ergebnisse und eine stabile Hülle für Daten verwenden.

Fortgeschritten~4 Min. LesezeitVeröffentlicht 2026-10-30Aktualisiert 2026-10-30
Drei API-Antwortformen und ihre Abwägungen

Kurz gesagt: Drücken Sie Ergebnisse mit 4xx/5xx-Statuscodes aus, tragen Sie die Payload in { "data": ..., "meta": ... } und wechseln Sie bei Fehlschlag zu einer error-Hülle; das genügt für interne APIs, und nur öffentliche Plattformen mit vielen Integratoren brauchen JSON:API oder OpenAPI.

Schließen Sie zuerst die schlechteste Option aus: immer 200 zurückzugeben, mit dem Ergebnis in einem code-Feld.

Drei Formen

A. Nacktes Objekt

{ "id": 1, "name": "demo", "price": 99 }

Sauber, und HTTP-Semantik erledigt die Arbeit (404 ist 404). Aber sobald Sie Paginierung, Warnungen oder eine Trace-id brauchen, gibt es keinen Platz dafür, ohne den Vertrag zu ändern.

B. Stabile Hülle

{
  "data": { "id": 1, "name": "demo" },
  "meta": { "requestId": "abc", "took": 12 }
}

Payload und Metadaten leben getrennt, neue Metadaten formen also nie data um. Kostet eine Verschachtelungsebene.

C. Alles-Hülle (vermeiden)

{ "code": 0, "message": "success", "data": {...} }

Die Form ist nicht die Sünde; die Praxis ist es. Status 200 für jedes Ergebnis bedeutet, dass CDNs, Gateways, Circuit Breaker, Retry-Richtlinien und Dashboards alle Erfolg sehen. Jeder Alarm braucht dann eigenes Parsen.

Die Empfehlung

HTTP-Status für das Ergebnis, Hülle für die Payload.

{
  "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 oder 5xx; code stabil und maschinenlesbar; message für Menschen; details für Formularfehler auf Feldebene.

Harte Regeln

  1. Listen-Endpunkte müssen Paginierungsmetadaten tragen. Ohne total oder einen Cursor gibt es keinen Pager.
  2. Leere Listen geben [] zurück, nie null. null.map ist ein wiederkehrender Ausfall.
  3. Zeitstempel in ISO 8601 mit Offset. Siehe welches Format für Zeitstempel.
  4. Eine Benennungskonvention. snake_case oder camelCase, einmal an der Grenze konvertiert.
  5. Geld als ganzzahlige kleinste Einheiten oder Strings. 99.99 ist in binärem Gleitkomma nicht exakt.
  6. null nicht mit fehlend verwechseln. Siehe null oder Feld weglassen.

Wann eine Spezifikation übernehmen

  • Öffentliche Plattformen mit vielen Integratoren: JSON:API oder OpenAPI plus eine geteilte Hülle
  • Interne APIs eines Teams: die obige Hülle genügt
  • Starke Verträge: Schema zuerst, Strukturen daraus generiert

Spezifikationen sparen Diskussion und senken die Einarbeitungskosten. Für ein Fünf-Personen-Team ist JSON:API meist negative Arbeit.

FAQ

Wie soll ich zwischen nacktem Objekt und Hülle wählen?

Verwenden Sie eine Hülle, wenn Sie Paginierung, Warnungen oder eine requestId brauchen, damit meta wachsen kann, ohne data umzuformen. Geben Sie das nackte Objekt nur zurück, wenn Sie keine Metadaten brauchen und akzeptieren können, dass spätere Felder den Vertrag ändern.

Warum sollte eine API nie für jedes Ergebnis 200 zurückgeben?

CDNs, Gateways, Circuit Breaker, Retry-Richtlinien und Dashboards lesen alle den HTTP-Status, um zu entscheiden, ob sie cachen, wiederholen oder alarmieren. Mit 200 überall behandeln sie Fehlschläge als Erfolge, und jeder Alarm braucht eigenes Parsen des Geschäftscodes.

Sollten Listen-Endpunkte Paginierungsmetadaten tragen?

Ja. Ohne total oder einen Cursor gibt es keinen Pager, und leere Listen müssen [] statt null zurückgeben, sonst bricht der .map-Aufruf im Frontend.

Weiterführende Literatur