2013-01-22 4 views
5

Ich wurde gebeten, eine RESTful API zu entwerfen und zu implementieren, und habe Best Practices erforscht, aber bisher nur ein wolliges Konzept über Ressourcendarstellungen. Die meisten verfügbaren Beispiele, die ich gefunden habe, scheinen sich stark auf API-Clients zu konzentrieren, die verbundene Strukturen mithilfe einer Reihe von GETs durchlaufen.REST-Ressourcendarstellung mit Links, kompatibel mit PUT und GET

Ich habe sah:

http://www.restapitutorial.com/media/RESTful_Best_Practices-v1_1.pdf

http://www.youtube.com/watch?v=HW9wWZHWhnI

unter anderem Online-Ressourcen (Ich bin zu 2 Links beschränkt leider kann sie nicht alle aufzählen). Sie sind alle großartig, aber nicht wirklich meine Design-Frage.

Die meisten der Best-Practice-Dokumente legen nahe, zwei Dinge zu mir, dass etwas in Konflikt aussehen:

1) REST-Service-Ressourcen Datenbeziehungen als Verbindungen zwischen

2) Einem "PUT" Anfrage von a darstellen sollte Der Client sollte eine vollständige Repräsentation sein, die der Darstellung auf dem Server entspricht.

Das Problem aus meiner Sicht ist, dass die Links und vielleicht einige andere Eigenschaften in einer typischen Ressource schreibgeschützt sind und daher nicht aktualisiert werden können. Der Server erwartet, dass sie unverändert bleiben und gibt einen Fehler zurück, wenn der Client denkt, dass der Client versucht, sie zu aktualisieren. Wenn ich mir eine typische Ressource anschaue, die in JSON vertreten ist, handelt es sich bei der Mehrzahl um Daten, die logisch nicht ersetzt werden können/sollten. Z.B.

{ 
"link": { "rel":"self", "href":"http://example/project/12345" }, 
"team": { 
    "link": { "rel":"self", "href":"http://example/project/12345/team" }, 
    "title": "The project team" 
    }, 
    "title": "The Big Project" 
} 

hier bestenfalls nur die beiden Titeltexte an einen Client auf dieser Ressource (Team Mitgliedschaft sein könnte über das Team Link änderbaren) wäre beschreibbar.

Also sollte ich verlangen, dass ein PUT enthält alle "Link" -Elemente genau wie sie sind, die rein logisch und schreibgeschützt sind (beachten Sie im Beispiel, das Team kann nicht neu verknüpft werden, wie die Ressource definiert es als Team für das Projekt - in diesem Fall könnte das geändert werden, aber für viele Ressourcenarten mit strengerem Containerschiff gilt dies nicht)?

Gibt es Standardmuster oder Antimuster für die Darstellung von Ressourcen in REST mit vielen Links? Ich werde nicht nach einer bestimmten REST-Variante wie HATEOAS gefragt, obwohl meine Neigung darin besteht, theoretische "Korrektheit" anzustreben, wo immer möglich. Mit anderen Worten, wenn "offizieller" REST zu erwarten wäre, dass die Kunden die gesamte Ressource, die Links und alles zusammenstellen, dann ist es wahrscheinlich das, was ich tun werde.

Einige Beispiele von reellen komplexen REST-Ressourcen, die GET und PUT unterstützen und daher mit diesem Problem arbeiten müssen, wären sehr willkommen. Wenn ich suche, bekomme ich viele Meinungen und viele Beispiele, die zeigen, wie schön GET funktioniert. . . aber bis jetzt habe ich kein gut dokumentiertes Beispiel gesehen, das eine PUT zu etwas anderem als einer trivialen Leaf-Ressource zeigt (d. h. eine, die keine Links enthält, außer vielleicht einer Selbstreferenz).

Antwort

1

Sie sollten eine "vollständige" Darstellung einfügen, da Ihr Medientyp sie definiert. Wenn Sie Ihren eigenen Medientyp entwerfen, sollte Ihre Spezifikation definieren, welche Teile veränderbar sein sollen und welche unveränderlich sein sollen.Das Shoji Katalog Protokoll zum Beispiel definiert a "body" member, die die veränderbaren Daten enthalten sollten:

Im Allgemeinen, wenn ein Körperteil vorhanden ist, Prozessoren die Werte innerhalb des Körpers erwarten sollten potenziell wandelbar sein (über eine HTTP PUT oder POST, zum Beispiel) und sollten erwarten, dass alle Werte außerhalb der Körper Mitglied unveränderlich sein; das heißt (möglicherweise) schreibbar auf einfügen, aber nicht auf update. Server sind frei, natürlich zu erlauben oder Mutabilität eines Teils der Ressource zu verbieten. Aber die Anwesenheit eines "body" -Mitglieds bringt starke Hinweise bezüglich der Veränderlichkeit von Daten sowohl innerhalb als auch außerhalb dieses Elements mit sich.

Dies ist kein Standard (obwohl es so offensichtlich nützlich für mich ist, dass ich möchte, dass es eins wird (Wink)). Beachten Sie, dass Server mit der Darstellung, die ein Client sendet, alles tun können, was sie wollen; Die stärkste Anforderung für jeden HTTP-Server ist, dass er versucht, die Intention des Clients auszuführen (wenn möglich und erlaubt). Wie und in welchem ​​Umfang es ist, ist wirklich ein Anliegen für Ihre spezielle Anwendung, weshalb Sie nicht viel in irgendwelchen Details darüber finden.

In der Praxis habe ich es nicht nützlich für den Server gefunden, die Links oder andere unveränderliche Teile einer Darstellung zu validieren; Sie werden einfach ignoriert. Das kann dazu führen, dass Kunden entscheiden, dass sie solche Dinge weglassen können. Auch in der Praxis habe ich das nicht als Problem empfunden.

+0

Vielen Dank. Mein mit Stiften versehenes Design enthält einen "Eigenschaften" -Abschnitt, der der Idee des "Körper" -Mitglieds ziemlich ähnlich sieht. Ich überlege auch, solche Dinge in ihre eigenen Blatt-Ressourcen zu brechen, die meinem Entwurf 5 oder 6 Ressourcentypen hinzufügen würden (schlecht), aber PUT-Methoden erheblich vereinfachen (gut) –

3

Im Grunde wird eine GET-Anforderung eine serialisierte Ressource in ein definiertes Format und Metadaten über diese Ressource (die zusammen eine Repräsentation der Ressource darstellen) zurückgeben. Wenn Sie eine Repräsentation zurückstellen, müssen sie weder die Metadaten enthalten noch müssen sie im selben Format wie die ursprüngliche (oder nachfolgende) GET-Anforderung sein. Der Server aktualisiert dann die Ressource basierend auf der von Ihnen bereitgestellten Darstellung.

Ein Beispiel aus HTML sind die Elemente und <body>, die Metadaten über die Ressource und die Ressourcendarstellung bereitstellen. und die text/html und application/x-www-form-urlencoded Inhaltstypen, die Ressourcendarstellungen in zwei verschiedenen Formaten übertragen, ersteres mit Metadaten, letzteres ohne. Wenn Sie die Ressource nach POST abholen, erwarten Sie nicht, application/x-www-form-urlencoded formatierte Daten zu erhalten!

Ich bin mir nicht sicher, was Sie mit "REST-Variante" meinen. Es gibt nur einen REST. Wenn Sie sich auf andere HTTP-basierte APIs beziehen, nennen Sie sie nicht REST. Weitere Informationen zu API-Stilen finden Sie unter Classification of HTTP-based APIs.

Zuletzt fragen Sie nach Beispielen für Nicht-Blatt-PUT-Anfragen. Ich bin nicht sicher genau das, was Sie von nicht-Blatt bedeuten, als ich von zwei Typen denken kann:

  1. Kollektionen
  2. Sub-Ressourcen

Kollektionen Können sagen, Sie haben ein Auto Katalog, verfügbar unter /cars. Wenn Sie entschieden haben, dass Sie alle Ihre Autos löschen möchten, können Sie entweder DELETE /cars/1, DELETE /cars/2 ... usw. oder Sie wählen PUT /cars mit einem leeren Körper oder einem Array ohne Inhalt. Letzteres wäre natürlich viel effizienter.

Sub-Ressourcen dieses Thema fortsetzen, können sagen, dass es ein Auto ist, /cars/1, die so dargestellt wird:

{ 
    "model":"Model-T", 
    "mfgr":"Ford", 
    "colour":"black" 
} 

Jetzt können Sie diese Felder durch URLs zugegriffen werden, um zu ermöglichen, wollen solche als /cars/1/mfgr, die Ford oder vielleicht {"mfgr":"Ford"} zurückgeben würde. Jetzt stellt die URL /cars/1 eine Nicht-Blatt-Ressource dar. Es gibt jedoch immer noch kein Problem beim Einfügen einer neuen Darstellung in die URL. Dies würde daher auch die Werte der Unterressourcen-URLs aktualisieren.

Zuletzt möchten Sie vielleicht das Format HAL für die Übertragung von Hypertext über JSON betrachten.

+0

Danke. HAL sieht für mich wie eine praktikable Option aus (über ROAR-Juwel), da ich mich wahrscheinlich auf Rubys Traubenjuwel niederlassen werde, um die API zu implementieren. –

+0

Gute Antwort. Ich mag die anfänglichen Kosten, Wartungskosten und Entwicklungskosten, die den API-Klassifizierungen in Ihrem Link zugewiesen sind. – codeasone

Verwandte Themen