2012-05-01 8 views
6

Betrachten Sie einen Benutzer (/ users/{id}) mit einem Namen und mehreren Speicherorten (/ users/{id}/locations).In RESTful-Webdiensten sollten Antwort-DTOs ihre untergeordneten DTOs enthalten?

Wenn ich einen Benutzer anfordere (/ user/{id}), sollte dieser Benutzer vollständig vertreten sein - seine ID, Name und Standorte - oder sollen Standorte nur auf eine separate Anfrage zurückgegeben werden? Zum Beispiel, welchen JSON DTO würden Sie bei einer Anfrage für einen Benutzer mit ID = 123 (/ users/123) erwarten:

1) {"id": 123, "name": "Peter", "locations": [{"id": 1, "name": "Chicago"}, {"id": 2, "name": "New York"}]}

2) {"id": 123, "name ":" Peter "," Standorte ": [{" id ": 1}, {" id ": 2}]}

3) {" id ": 123," name ":" Peter "," Standorte ": [1, 2]}

4) { "id": 123, "name":" Peter“}

Ist das mehr subjektiv, schieben und Ziehen zwischen der Größe der DTOs und Anforderungen im typischen Anwendungsfall? Ich neige dazu, einfach alle relevanten Daten einzubeziehen (1), aber ich bin nicht sicher, dass es besser ist, als Entwickler nur dazu zu zwingen, mehrere Aufrufe an eine API zu senden, um alle der Daten zu erhalten, die sie tatsächlich wollen.

+1

Gibt es Gründe, warum Sie nicht einen Abfrageparameter hinzufügen würde Unterelement Sammlungen zum Ein-/Aus-Listing? Das wäre nicht anders als das Hinzufügen eines?format = {json | xhtml} zum Anpassen des Formats der Ausgabe ... – ScottCher

+0

Hauptsächlich wegen der Entwicklungszeit; Ich möchte keine unerwarteten oder unnötigen Ergänzungen einführen. Ich möchte einfach "richtig" oder zumindest auf eine vernünftige, schnelle Art und Weise handeln. –

Antwort

3

Um RESTful Sie müssen nicht unbedingt die vollständige Darstellung der Ressource zurückgeben. Sie möchten jedoch Hypermedia als Mittel zum Abrufen/Festlegen aller Informationen aktivieren, die der Benutzer Ihrer API benötigt (Hypermedia als die Engine des Anwendungsstatus - HATEOAS)

Um dies zu erfüllen, können Sie entweder den Vorschlag von @bowmanb zu p verwenden Verwenden Sie einen URI für alle Standorte oder fügen Sie einzelne URIs für jeden Standort hinzu. Wahrscheinlich möchten Sie zusätzliche URIs für andere Optionen hinzufügen, um etwas mit der Ressource zu tun.

Es gibt einen guten Artikel über HATEOAS von Jim Webber, Savas Parastatidis & Ian Robinson genannt "how to GET a cup of coffee"

2

Ich bin ein Neuling in dieser Welt, aber ich baue eine erholsame api und konfrontiert genau das gleiche Problem. Meine anfängliche Arbeit bestand darin, alles einzubeziehen - so sehen meine Ergebnisse wie Ihre Option aus (1). Tatsächlich gehe ich ein wenig weiter und habe eine URI mit jedem Objekt integriert, so dass theoretisch die Antwort von einem ausreichend intelligenten Client gesteuert werden kann.

Nachdem ich das gesagt habe, habe ich festgestellt, dass ein bestimmtes Attribut meiner Entsprechung zu Ihrem "Benutzer" -Objekt enorm ist. Es scheint nicht die Leistung zu beeinträchtigen, aber es scheint mir, dass kein Kunde all diese Informationen über dieses bestimmte Attribut möchte - die meisten Kunden würden nur die ID und den Namen wollen. Also werde ich meinen Standardansatz für dieses Attribut ändern.

Unterm Strich - in meiner Newbie-Meinung - ist, dass die Entscheidung von der erwarteten Nutzung Ihrer Kunden getrieben wird - was würde der Kunde sehen wollen?

1

Es sollte einen Weg geben, auf dem ein Client bestimmen kann, wie er die Standorte eines Benutzers findet. So würde ich Zahl ausschließen 4.

Wenn Sie besorgt über die Größe Ihrer Antwort sind, glaube ich es noch RESTful wäre nur die URI eines Benutzers Standorte umfassen:

{ "id":123, "name":"Peter", "locations":"https://stackoverflow.com/users/123/locations" } 
+0

Dann wäre vermutlich Ihre Sammlung von Standorten individuelle URI-Referenzen zu jedem Standort? zB/locations/{locationid} – ScottCher

+0

Das habe ich mir gedacht. Wenn die Standorte eines Benutzers für den Dienst wichtig sind und die Größe der Antwort keine Rolle spielt, würde ich alles in die/users/{id} -Antwort aufnehmen, einschließlich der URI (wie @Arnon Rotem-Gal-Oz sagte). '{" id ": 123," name ":" Peter "," Standorte ": [{" id ": 1," name ":" Chicago "," uri ":"/users/123/locations/1 " }, {"id": 2, "name": "New York", "uri": "/ users/123/locations/2"}]} ' – anon