Gibt es Standards oder Best Practices für die Strukturierung von JSON-Antworten über eine API? Offensichtlich sind die Daten jeder Anwendung unterschiedlich, so dass ich mich nicht so sehr mit dem "Antwort-Boilerplate" befasse, wenn Sie so wollen. Ein Beispiel für das, was ich meine:
Erfolgreiche Anfrage:
{
"success": true,
"payload": {
/* Application-specific data would go here. */
}
}
Fehlgeschlagene Anfrage:
{
"success": false,
"payload": {
/* Application-specific data would go here. */
},
"error": {
"code": 123,
"message": "An error occurred!"
}
}
Antworten:
Ja, es sind einige Standards (wenn auch einige Freiheiten bei der Definition von Standards) aufgetaucht:
Es gibt auch JSON-API-Beschreibungsformate:
quelle
Google JSON-Leitfaden
Erfolgsantwort zurück
data
Rückgabe der Fehlerantwort
error
Wenn Ihr Client JS ist, können Sie
if ("error" in response) {}
überprüfen, ob ein Fehler vorliegt.quelle
error
, Googles Seite gibt ein Beispiel dafürIch denke, ein Defacto-Standard ist nicht wirklich entstanden (und wird es vielleicht nie). Aber egal, hier ist meine Einstellung:
Erfolgreiche Anfrage:
Fehlgeschlagene Anfrage:
Vorteil: Gleiche Elemente der obersten Ebene in Erfolgs- und Fehlerfällen
Nachteil: Kein Fehlercode, aber wenn Sie möchten, können Sie entweder den Status in einen (Erfolgs- oder Fehler-) Code ändern oder ein weiteres Element der obersten Ebene mit dem Namen "Code" hinzufügen.
quelle
messages
das ein Array von Nachrichten anstelle einer einzelnen Zeichenfolge ist.fail
für typische Validierungsprobleme, währenderror
sie nur bei Fatalen wie DB-Fehlern verwendet werden.200
in den köpfen steht, warum brauchst du überhaupt einstatus
feld? Geben Sie das Datenobjekt einfach gerade zurück. Sie wissen, dass dies bei typisierten FE-Sprachen wie TypeScript zusätzliche Schmerzen verursachen kann.Angenommen, Ihre Frage bezieht sich auf das Design von REST-Webservices und genauer auf Erfolg / Fehler.
Ich denke, es gibt 3 verschiedene Arten von Design.
Verwenden Sie nur den HTTP-Statuscode, um anzuzeigen, ob ein Fehler aufgetreten ist, und versuchen Sie, sich auf die Standardfehler zu beschränken (normalerweise sollte dies ausreichen).
Verwenden Sie HTTP Status + json body (auch wenn es sich um einen Fehler handelt). Definieren Sie eine einheitliche Struktur für Fehler (z. B. Code, Nachricht, Grund, Typ usw.) und verwenden Sie sie für Fehler. Wenn dies erfolgreich ist, geben Sie einfach die erwartete JSON-Antwort zurück.
Vergessen Sie den http-Status (z. B. immer Status 200), verwenden Sie immer json und fügen Sie im Stammverzeichnis der Antwort einen booleschen responseValid und ein Fehlerobjekt (Code, Nachricht usw.) hinzu, die ausgefüllt werden, wenn es sich um einen Fehler handelt, andernfalls die anderen Felder (Erfolg) sind besiedelt.
Vorteile: Der Client behandelt nur den Hauptteil der Antwort, bei dem es sich um eine JSON-Zeichenfolge handelt, und ignoriert den Status (?).
Nachteile: Je weniger Standard.
Es liegt an Ihnen zu wählen :)
Abhängig von der API würde ich 2 oder 3 wählen (ich bevorzuge 2 für json rest apis). Eine andere Sache, die ich beim Entwerfen von REST-API erlebt habe, ist die Wichtigkeit der Dokumentation für jede Ressource (URL): die Parameter, den Körper, die Antwort, die Header usw. + Beispiele.
Ich würde Ihnen auch empfehlen, jersey (jax-rs-Implementierung) + genson (java / json-Datenbindungsbibliothek) zu verwenden. Sie müssen nur genson + jersey in Ihren Klassenpfad legen und json wird automatisch unterstützt.
BEARBEITEN:
Lösung 2 ist am schwierigsten zu implementieren, aber der Vorteil ist, dass Sie Ausnahmen und nicht nur Geschäftsfehler gut behandeln können. Der anfängliche Aufwand ist wichtiger, aber Sie gewinnen langfristig.
Lösung 3 ist sowohl auf der Serverseite als auch auf dem Client einfach zu implementieren, aber nicht so schön, da Sie die Objekte, die Sie zurückgeben möchten, in ein Antwortobjekt einkapseln müssen, das auch den Fehler responseValid + enthält.
quelle
Der RFC 7807: Problemdetails für HTTP-APIs kommt derzeit einem offiziellen Standard am nächsten.
quelle
Im Folgenden wird das von Instagram verwendete JSON-Format aufgeführt
quelle
Ich werde nicht so arrogant sein zu behaupten, dass dies ein Standard ist, also werde ich das Formular "Ich bevorzuge" verwenden.
Ich bevorzuge eine knappe Antwort (wenn ich eine Liste von / Artikeln anfordere, möchte ich ein JSON-Array von Artikeln).
In meinen Designs verwende ich HTTP für den Statusbericht, ein 200 gibt nur die Nutzdaten zurück.
400 gibt eine Nachricht zurück, was mit der Anfrage falsch war:
Geben Sie 404 zurück, wenn das Modell / der Controller / der URI nicht vorhanden ist
Wenn auf meiner Seite ein Fehler bei der Verarbeitung aufgetreten ist, gebe ich 501 mit einer Nachricht zurück:
Nach dem, was ich gesehen habe, tendieren einige REST-ähnliche Frameworks dazu, in diese Richtung zu gehen.
Begründung :
JSON soll ein Nutzdatenformat sein , es ist kein Sitzungsprotokoll. Die ganze Idee von ausführlichen sitzungsbezogenen Nutzdaten stammt aus der XML / SOAP-Welt und verschiedenen fehlgeleiteten Entscheidungen, die diese aufgeblähten Designs hervorgebracht haben. Nachdem wir festgestellt hatten, dass dies alles massive Kopfschmerzen waren, bestand der Sinn von REST / JSON darin, es zu küssen und an HTTP festzuhalten. Ich glaube nicht, dass es in JSend irgendetwas im entferntesten Standard gibt, und vor allem nicht in den ausführlicheren unter ihnen. XHR reagiert auf HTTP-Antworten. Wenn Sie jQuery für Ihre AJAX verwenden (wie die meisten), können Sie
try
/catch
unddone()
/fail()
Rückrufe verwenden, um Fehler zu erfassen. Ich kann nicht sehen, wie nützlich es ist, Statusberichte in JSON zu kapseln.quelle
Für das, was es wert ist, mache ich das anders. Ein erfolgreicher Aufruf enthält nur die JSON-Objekte. Ich benötige kein übergeordnetes JSON-Objekt, das ein Erfolgsfeld enthält, das true angibt, und ein Nutzdatenfeld, das das JSON-Objekt enthält. Ich gebe nur das entsprechende JSON-Objekt mit einer 200 zurück oder was auch immer im Bereich 200 für den HTTP-Status im Header geeignet ist.
Wenn jedoch ein Fehler auftritt (etwas in der 400er-Familie), gebe ich ein wohlgeformtes JSON-Fehlerobjekt zurück. Wenn der Client beispielsweise einen Benutzer mit einer E-Mail-Adresse und einer Telefonnummer postet und eine davon fehlerhaft ist (dh ich kann sie nicht in meine zugrunde liegende Datenbank einfügen), gebe ich Folgendes zurück:
Wichtige Punkte hierbei sind, dass die Eigenschaft "field" genau mit dem JSON-Feld übereinstimmen muss, das nicht validiert werden konnte. Auf diese Weise können Kunden genau wissen, was bei ihrer Anfrage schief gelaufen ist. Außerdem befindet sich "Nachricht" im Gebietsschema der Anforderung. Wenn sowohl "emailAddress" als auch "phoneNumber" ungültig wären, würde das Array "Errors" Einträge für beide enthalten. Ein 409 (Conflict) JSON-Antworttext könnte folgendermaßen aussehen:
Mit dem HTTP-Statuscode und diesem JSON verfügt der Client über alles, was er benötigt, um deterministisch auf Fehler zu reagieren, und es wird kein neuer Fehlerstandard erstellt, der versucht, die HTTP-Statuscodes vollständig zu ersetzen. Beachten Sie, dass diese nur für den Bereich von 400 Fehlern auftreten. Für alles im Bereich 200 kann ich einfach alles zurückgeben, was angemessen ist. Für mich ist es oft ein HAL-ähnliches JSON-Objekt, aber das spielt hier keine Rolle.
Das einzige, was ich über das Hinzufügen nachgedacht habe, war ein numerischer Fehlercode, entweder in den Array-Einträgen "Fehler" oder im Stammverzeichnis des JSON-Objekts. Aber bisher haben wir es nicht gebraucht.
quelle
Es besteht keine Einigung über die übrigen API-Antwortformate großer Software-Giganten - Google, Facebook, Twitter, Amazon und andere, obwohl in den obigen Antworten viele Links angegeben wurden, bei denen einige Leute versucht haben, das Antwortformat zu standardisieren.
Da die Anforderungen der APIs unterschiedlich sein können, ist es sehr schwierig, alle an Bord zu bringen und einem bestimmten Format zuzustimmen. Wenn Millionen von Benutzern Ihre API verwenden, warum sollten Sie Ihr Antwortformat ändern?
Im Folgenden sehe ich das Antwortformat, das von Google, Twitter, Amazon und einigen Posts im Internet inspiriert wurde:
https://github.com/adnan-kamili/rest-api-response-format
Swagger-Datei:
https://github.com/adnan-kamili/swagger-sample-template
quelle
Der Punkt von JSON ist, dass es vollständig dynamisch und flexibel ist. Biegen Sie es nach Belieben, da es sich nur um eine Reihe von serialisierten JavaScript-Objekten und -Arrays handelt, die in einem einzelnen Knoten verwurzelt sind.
Was der Typ des Wurzelknotens ist, liegt bei Ihnen, was er enthält, liegt bei Ihnen, ob Sie Metadaten zusammen mit der Antwort senden, liegt bei Ihnen, ob Sie den MIME-Typ auf setzen
application/json
oder ihntext/plain
Ihnen überlassen ( solange Sie wissen, wie man mit den Randfällen umgeht).Erstellen Sie ein leichtes Schema, das Ihnen gefällt.
Persönlich habe ich festgestellt , dass Analytics-Tracking - und mp3 / ogg dienen und Bildgalerie dient , und Text-Messaging und Netzwerk-Pakete , die für Online - Spiele und Blog-Beiträge und Blog-Kommentare alle haben sehr unterschiedliche Anforderungen in Bezug auf was ist gesendet und was empfangen wird und wie sie verbraucht werden sollen.
Das Letzte, was ich bei all dem tun möchte, ist zu versuchen, jeden einzelnen an denselben Boilerplate-Standard anzupassen, der auf XML2.0 oder ähnlichem basiert.
Das heißt, es ist eine Menge für die Verwendung von Schemata zu sagen , die Sinn machen Sie und sind gut durchdacht.
Lesen Sie einfach einige API-Antworten, notieren Sie, was Ihnen gefällt, kritisieren Sie, was Sie nicht mögen, schreiben Sie diese Kritik auf und verstehen Sie, warum sie Sie falsch reiben, und überlegen Sie dann, wie Sie das Gelernte auf das anwenden können, was Sie brauchen.
quelle
JSON-RPC 2.0 definiert ein Standard-Anforderungs- und Antwortformat und ist nach der Arbeit mit REST-APIs ein Hauch frischer Luft.
quelle
code
Feld ein String ist. Glücklicherweise erlaubt uns die Spezifikation, alle gewünschten Informationen in das Fehlerfelddata
einzufügen. In meinen JSON-RPC-Projekten verwende ich normalerweise einen einzigen numerischen Code für alle Fehler auf Anwendungsebene (im Gegensatz zu einem der Standardprotokollfehler). Dann habe ich die detaillierten Fehlerinformationen (einschließlich eines Zeichenfolgencodes, der den tatsächlichen Fehlertyp angibt) in dasdata
Feld eingefügt.Für diejenigen, die später kommen, würde ich zusätzlich zu der akzeptierten Antwort, die HAL, JSend und JSON API enthält, einige andere Spezifikationen hinzufügen, die es wert sind, untersucht zu werden:
quelle
Das vorgeschlagene Grundgerüst sieht gut aus, aber das definierte Fehlerobjekt ist zu begrenzt. Oft kann man nicht einen einzigen Wert verwenden, um das Problem auszudrücken, sondern es wird eine Kette von Problemen und Ursachen benötigt .
Ich habe ein wenig recherchiert und festgestellt, dass das häufigste Format für die Rückgabe von Fehlern (Ausnahmen) eine Struktur dieser Form ist:
Dies ist das vom OASIS-Datenstandard OASIS OData vorgeschlagene Format und scheint die Standardoption auf dem Markt zu sein. Derzeit scheint es jedoch keine hohen Akzeptanzraten für einen Standard zu geben. Dieses Format stimmt mit der JSON-RPC-Spezifikation überein.
Die vollständige Open Source-Bibliothek, die dies implementiert, finden Sie unter: Mendocino JSON Utilities . Diese Bibliothek unterstützt sowohl die JSON-Objekte als auch die Ausnahmen.
Die Details werden in meinem Blogbeitrag zur Fehlerbehandlung in der JSON REST-API erläutert
quelle
Es gibt keinen anderen gesetzeswidrigen oder gesetzwidrigen Standard als den gesunden Menschenverstand. Wenn wir dies wie zwei sprechende Personen abstrahieren, ist der Standard der beste Weg, um sich in minimalen Worten in kürzester Zeit genau zu verstehen. In unserem Fall optimiert "Minimum Words" die Bandbreite für die Transporteffizienz und "genau verstehen" ist die Struktur für die Parser-Effizienz. was letztendlich dazu führt, dass weniger Daten und die gemeinsame Struktur vorhanden sind; so dass es durch ein Nadelloch gehen und durch ein gemeinsames Zielfernrohr analysiert werden kann (zumindest anfangs).
Fast in allen vorgeschlagenen Fällen sehe ich getrennte Antworten für das Szenario "Erfolg" und "Fehler", was für mich eine Art Mehrdeutigkeit darstellt. Wenn die Antworten in diesen beiden Fällen unterschiedlich sind, warum müssen wir dann wirklich dort ein "Erfolg" -Flag setzen? Ist es nicht offensichtlich, dass das Fehlen von "Fehler" ein "Erfolg" ist? Ist es möglich, eine Antwort zu erhalten, bei der 'Erfolg' WAHR ist und ein 'Fehler' gesetzt ist? Oder ist 'Erfolg' FALSCH, ohne dass 'Fehler' gesetzt ist? Nur eine Flagge ist nicht genug? Ich würde es vorziehen, nur das Flag "Fehler" zu haben, da ich glaube, dass es weniger "Fehler" als "Erfolg" geben wird.
Sollten wir den "Fehler" auch wirklich zu einer Flagge machen? Was ist, wenn ich mit mehreren Validierungsfehlern antworten möchte? Daher finde ich es effizienter, einen 'Fehler'-Knoten zu haben, bei dem jeder Fehler diesem Knoten untergeordnet ist. wobei ein leerer (bis Null zählender) "Fehler" -Knoten einen "Erfolg" bedeuten würde.
quelle
Beste Antwort für Web-APIs, die von mobilen Entwicklern leicht verstanden werden können.
Dies ist für die Antwort "Erfolg"
Dies ist für "Fehler" Antwort
quelle