Wie kann ein Array in einer RESTful-API am besten als Antwort zurückgegeben werden?

40

Angenommen, wir haben Ressourcen wie diese,

book:
    type: object
    properties:
        author: {type: string}
        isbn: {type: string}
        title: {type: string}

books:
    type: array
    items: book

Wenn also jemand eine GETRessource für Bücher erstellt, geben wir Folgendes zurück

[{"author": "Dan Brown", "isbn": "123456", "title": "Digital Fortress"},
 {"author": "JK Rowling", "isbn": "234567", "title": "Harry Potter and the Chamber of Secrets"}]

Ich habe von jemandem auf der Arbeit gehört, dass die empfohlene REST-Methode darin besteht, Antworten immer als JSON-Objekte zurückzugeben. booksDies würde bedeuten, dass unser Schema für folgendermaßen aussehen würde:

books:
    type: object
    properties:
        list:
            type: array
            items: book

Also, jetzt würde die Antwort so aussehen,

{
    "list": [{"author": "Dan Brown", "isbn": "123456", "title": "Digital Fortress"},
             {"author": "JK Rowling", "isbn": "234567", "title": "Harry Potter and the Chamber of Secrets"}]
}

Welche davon ist die beste REST-Praxis?

geborener Kreuzfahrer
quelle
1
ist JSON RESTful? solltest du sicher html zurückgeben?
Ewan
3
@Ewan: Die Nutzlast spielt keine Rolle. Dafür gibt es MIME-Typen.
Robert Harvey
1
Weder sind Best Practice für REST. REST besteht aus HATEOAS, was bedeutet, dass Ihre API auffindbar ist. Suchen Sie nach HAL oder JSON-LD.
Florian Margaine
Json-ld: Arbeite dich langsam auf WCF zu
Ewan
Nach dem, was ich gelesen habe, ist das Umschließen von JSON-Arrays in einem Objekt eine Abwehrmaßnahme gegen eine gemeldete Sicherheitsanfälligkeit in älteren Browsern - haacked.com/archive/2009/06/25/json-hijacking.aspx . Dies scheint in modernen Browers von heute behoben worden zu sein. Ich denke, es ist besser in Sicherheit als in Verlegenheit.
Gishu

Antworten:

35

In der Praxis ist die zweite Option die beste Praxis. Der Grund dafür ist, dass Sie die Ressource überhaupt nicht erweitern können, wenn Sie nur ein Array zurückgeben.

Beispiel: Wenn Sie eine Anzahl aller Datensätze hinzufügen müssen, ist der Ansatz "Nur Array" bereits abgeschlossen.

Wenn dies in einer Listen-API vorkommt, möchten Sie diese konsistent halten, also alle Objekte zu einem Objekt machen. Dann wird Ihre API konsistenter und für Entwickler einfacher zu verwenden.

Beispiel: Nehmen wir an, ein Entwickler schreibt allgemeinen Code, um mithilfe Ihrer API Listen- und Detailseiten anzuzeigen. Er möchte keine Ausnahme erstellen, da es sich manchmal um ein Array und manchmal um ein Objekt mit einer Listeneigenschaft handelt.

Insgesamt hat diese Antwort nichts mit Grundsätzen über Ruhe, Hass und andere Protokolle zu tun, sondern nur mit den Daten, die Sie an den Kunden senden müssen. Wenn Sie sich zum Beispiel dafür entscheiden, Hassern zu folgen, dann halten Sie sich natürlich an ihre Standards (was übrigens auch Objekte sind).

Luc Franken
quelle
3
+1 für "Echtheit in Bezug auf Daten" (und obwohl immer noch anerkannt wird, dass es eine technischere und genauere Definition für REST gibt).
Donnerstag,
8

Beide

[{"author": "Dan Brown", "isbn": "123456", "title": "Digital Fortress"},{"author": "JK Rowling", "isbn": "234567", "title": "Harry Potter and the Chamber of Secrets"}]

und

{
    "list": [{"author": "Dan Brown", "isbn": "123456", "title": "Digital Fortress"},
         {"author": "JK Rowling", "isbn": "234567", "title": "Harry Potter and the Chamber of Secrets"}]
}

sind gültige Json. Ich denke nicht, dass Sie "Liste" hinzufügen sollten, wenn es nicht benötigt wird, es könnte sogar verwirrend sein, weil das, was darauf folgt, ein Array anstelle einer Liste ist.

Beste REST-Praxis? Die API sollte auf alle Einstellungen im Accept-Header und auf eine gute Dokumentation reagieren.

imel96
quelle
7

Der Grund, warum Sie Ihre Antwort JSON-kompatibel machen, ist, dass JSON ein defacto-Standard ist. Jede Sprache mit einem JSON-Parser kann sie trivial analysieren. Wenn Sie JavaScript verwenden, benötigen Sie nicht einmal einen Parser, da JavaScript sie von Haus aus versteht.

Mit anderen Worten, machen Sie es JSON-konform und Sie müssen keinen eigenen Parser schreiben. Darüber hinaus wird es keine Überraschungen geben, wenn der nächste Entwickler Software schreibt, die den Service nutzt.

REST hat nichts mit Ihrem JSON-Schema zu tun. Beide Schemata sind aus REST-Sicht akzeptabel.

Robert Harvey
quelle
9
Beantwortet das die Frage? Ich las es als "Sollte ich ein Json-Array oder ein Json-Objekt als root verwenden?". Beide können mit JSON-Parsern analysiert werden, sodass Ihre Antwort ihnen bei der Entscheidung nicht hilft.
CodesInChaos
Dann ist es egal. Ich habe meine Antwort aktualisiert.
Robert Harvey
Wenn es sich um REST handelt, spielt das Schema keine Rolle, solange es in der Lage ist, die Hypermedia-Steuerelemente für die Ermittlung und Bearbeitung weiterer Ressourcen bereitzustellen, die allein auf der Antwort und keinen anderen bandexternen Informationen beruhen Keines der vom OP genannten Formate scheint zu funktionieren.
toniedzwiedz
...and if you're using JavaScript, you don't even need a parser since JavaScript understands it natively.Ja und nein JSON ist eine Teilmenge von JavaScript, aber das Aufrufen evalanstelle der Verwendung eines Parsers macht Sie sofort anfällig für "JSON", das schädlichen Code enthält, und das Parsen ist höchstwahrscheinlich weitaus effizienter als evaljemals zuvor.
Doval
5

Ein Wörterbuch mit einem einzigen bedeutungslosen Schlüssel "list" und einem Array-Wert ist sinnlos - geben Sie stattdessen ein Array zurück.

Wenn derselbe Dienst Bücher, CDs oder DVDs zurückgeben könnte, könnten Sie ein Wörterbuch mit einem Schlüssel "books" und einem Array-Wert zurückgeben. Es könnte einen anderen Schlüssel "DVDs" mit einer Reihe von DVDs geben. Zum Beispiel, wenn ein Kunde eine Liste aller seiner Einkäufe abfragen kann.

Wenn Sie sicher sind, dass die Antwort nur als eine Liste von Büchern interpretiert wird (wenn die Aufforderung "Gib mir eine Liste von Büchern" lautet), ist nur ein Array in Ordnung.

gnasher729
quelle
5

Die zweite Option ist aus Sicherheitsgründen ebenfalls die bevorzugte Methode. Ältere Browser weisen eine Sicherheitslücke auf, die es anderen Javascript-Codes auf der Webseite ermöglicht, Ihre Daten zu stehlen, wenn sie als JSON-Array zurückgegeben werden. In der Vergangenheit war es daher die beste Vorgehensweise, keine JSON-Arrays zurückzugeben. Tatsächlich gab es einige Frameworks, deren "json-ify" -Funktion standardmäßig Option 2 auswählt, wenn Sie ein Array übergeben.

https://stackoverflow.com/questions/3503102/what-are-top-level-json-arrays-and-why-are-the-a-security-risk

http://ejohn.org/blog/re-securing-json/

Futter
quelle
1

beide sind json und halten sich an REST. Ich würde die Antwort aussagekräftiger gestalten, in Ihrem Fall die Änderungsliste zu Büchern. Oder so ähnlich :

{ "responceObject" : {

   results : 2,

    "Books": [
        {"author": "Dan Brown", "isbn": "123456", "title": "Digital Fortress"},
        {"author": "JK Rowling", "isbn": "234567", "title": "Harry Potter and the Chamber of Secrets"}
    ]

}}
MeganFoxObama
quelle