642 Stimmen

REST verstehen: Verben, Fehlercodes und Authentifizierung

Ich bin auf der Suche nach einer Möglichkeit, APIs um Standardfunktionen in meinen PHP-basierten Webanwendungen, Datenbanken und CMSs zu wickeln.

Ich habe mich umgesehen und mehrere "Skelett"-Frameworks gefunden. Zusätzlich zu den Antworten in meiner Frage gibt es Tonic ein REST-Framework, das ich mag, weil es sehr leichtgewichtig ist.

REST gefällt mir wegen seiner Einfachheit am besten, und ich möchte eine darauf basierende API-Architektur erstellen. Ich versuche, die grundlegenden Prinzipien zu verstehen und habe sie noch nicht ganz durchschaut. Daher eine Reihe von Fragen.

1. Verstehe ich es richtig?

Angenommen, ich habe eine Ressource "Benutzer". Ich könnte eine Reihe von URIs wie folgt einrichten:

/api/users     when called with GET, lists users
/api/users     when called with POST, creates user record
/api/users/1   when called with GET, shows user record
               when called with PUT, updates user record
               when called with DELETE, deletes user record

Ist dies bisher eine korrekte Darstellung einer RESTful-Architektur?

2. Ich brauche mehr Verben

Erstellen, Aktualisieren und Löschen mögen in der Theorie ausreichen, aber in der Praxis werde ich viel mehr Verben benötigen. Mir ist klar, dass dies Dinge sind, die pourrait in eine Aktualisierungsanforderung eingebettet werden, aber es handelt sich um spezifische Aktionen, die spezifische Rückgabewerte haben können, und ich möchte sie nicht alle in eine einzige Aktion packen.

Einige, die mir im Zusammenhang mit dem Benutzerbeispiel einfallen, sind:

activate_login
deactivate_login
change_password
add_credit

Wie würde ich Aktionen wie diese in einer RESTful-URL-Architektur ausdrücken?

Mein Instinkt wäre es, einen GET-Aufruf an eine URL wie

/api/users/1/activate_login 

und erwarten einen Statuscode zurück.

Das weicht jedoch von der Idee der Verwendung von HTTP-Verben ab. Was halten Sie davon?

3. Wie man Fehlermeldungen und Codes zurückgibt

Ein großer Teil der Schönheit von REST ergibt sich aus der Verwendung von Standard-HTTP-Methoden. Bei einem Fehler gebe ich eine Kopfzeile mit einem 3xx, 4xx oder 5xx Fehlerstatuscode aus. Für eine detaillierte Fehlerbeschreibung kann ich den Body verwenden (richtig?). So weit, so gut. Aber wie kann ich eine proprietärer Fehlercode die detaillierter beschreibt, was schief gelaufen ist (z.B. "Verbindung zur Datenbank fehlgeschlagen" oder "Datenbankanmeldung falsch")? Wenn ich sie zusammen mit der Meldung in den Textkörper einfüge, muss ich sie anschließend auslesen. Gibt es einen Standard-Header für diese Art von Meldungen?

4. Wie erfolgt die Authentifizierung?

  • Wie würde eine auf API-Schlüssel basierende Authentifizierung nach REST-Grundsätzen aussehen?
  • Gibt es gute Gründe, die gegen die Verwendung von Sitzungen bei der Authentifizierung eines REST-Clients sprechen, abgesehen davon, dass es ein eklatanter Verstoß gegen das REST-Prinzip ist? :) (Das ist nur ein halber Scherz, sitzungsbasierte Authentifizierung würde gut zu meiner bestehenden Infrastruktur passen).

17 Stimmen

@Daniel, danke für die Bearbeitung. "Ich mehr Verben" war ein absichtliches Wortspiel, aber ich lasse es so, es ist jetzt leichter zu lesen :)

1 Stimmen

Übrigens, zur Fehlerbeschreibung. Ich habe es geschafft, die Fehlerbeschreibung in die Kopfzeile der Antwort zu schreiben. Fügen Sie einfach eine Kopfzeile mit dem Namen "Fehlerbeschreibung" hinzu.

0 Stimmen

Dies sieht eher nach Fragen der Anwendungssicherheit aus. Anwendungssicherheit ist nicht das, worum es bei REST geht.

661voto

Daniel Vassallo Punkte 325264

Ich habe diese Frage mit ein paar Tagen Verspätung bemerkt, aber ich glaube, dass ich etwas dazu beitragen kann. Ich hoffe, dies kann hilfreich sein, um Ihre RESTful Venture.


Punkt 1: Verstehe ich es richtig?

Sie haben richtig verstanden. Das ist eine korrekte Darstellung einer RESTful-Architektur. Die folgende Matrix finden Sie unter Wikipedia sehr hilfreich bei der Definition Ihrer Substantive und Verben:


Beim Umgang mit einer Sammlung URI wie: http://example.com/resources/

  • GET : Auflistung der Mitglieder der Sammlung mit den URIs der Mitglieder zur weiteren Navigation. Listen Sie zum Beispiel alle zum Verkauf stehenden Autos auf.

  • PUT : Bedeutung definiert als "die gesamte Sammlung durch eine andere Sammlung ersetzen".

  • POST : Erstellen eines neuen Eintrags in der Sammlung, wobei die ID automatisch von der Sammlung zugewiesen wird. Die erstellte ID ist in der Regel Teil der Daten, die von diesem Vorgang zurückgegeben werden.

  • DELETE : Bedeutung definiert als "die gesamte Sammlung löschen".


Beim Umgang mit einer Mitglied URI wie: http://example.com/resources/7HOU57Y

  • GET : Abruf einer Darstellung des adressierten Mitglieds der Sammlung, ausgedrückt in einem geeigneten MIME-Typ.

  • PUT : Aktualisieren Sie das adressierte Mitglied der Sammlung oder erstellen Sie es mit der angegebenen ID.

  • POST : Behandelt das angesprochene Mitglied als eigenständige Sammlung und legt eine neue, untergeordnete Sammlung an.

  • DELETE : Löscht das adressierte Mitglied der Sammlung.


Punkt 2: Ich brauche mehr Verben

Wenn Sie denken, dass Sie mehr Verben brauchen, kann das bedeuten, dass Ihre Ressourcen neu identifiziert werden müssen. Denken Sie daran, dass Sie bei REST immer auf eine Ressource oder auf eine Sammlung von Ressourcen einwirken. Was Sie als Ressource wählen, ist für Ihre API-Definition ziemlich wichtig.

Aktivieren/Deaktivieren der Anmeldung : Wenn Sie eine neue Sitzung erstellen, sollten Sie "die Sitzung" als Ressource betrachten. Um eine neue Sitzung zu erstellen, verwenden Sie POST an http://example.com/sessions/ mit den Beglaubigungsschreiben im Körper. Um sie ablaufen zu lassen, verwenden Sie PUT oder DELETE (je nachdem, ob Sie einen Sitzungsverlauf aufbewahren möchten) an http://example.com/sessions/SESSION_ID .

Passwort ändern: Dieses Mal ist die Ressource "der Benutzer". Sie bräuchten ein PUT an http://example.com/users/USER_ID mit dem alten und dem neuen Kennwort im Hauptteil. Sie handeln mit der Ressource "Benutzer", und eine Kennwortänderung ist einfach eine Aktualisierungsanfrage. Sie ist der UPDATE-Anweisung in einer relationalen Datenbank sehr ähnlich.

Mein Instinkt wäre, einen GET-Anruf zu tätigen. an eine URL wie /api/users/1/activate_login

Dies verstößt gegen ein zentrales REST-Prinzip: die korrekte Verwendung von HTTP-Verben. Jede GET-Anfrage sollte niemals einen Nebeneffekt hinterlassen.

Eine GET-Anfrage sollte beispielsweise niemals eine Sitzung in der Datenbank erstellen, ein Cookie mit einer neuen Sitzungs-ID zurückgeben oder irgendwelche Rückstände auf dem Server hinterlassen. Das GET-Verb ist wie die SELECT-Anweisung in einer Datenbank-Engine. Denken Sie daran, dass die Antwort auf eine Anfrage mit dem Verb GET bei einer Anfrage mit denselben Parametern zwischengespeichert werden sollte, genau wie bei der Anfrage einer statischen Web-Seite.


Punkt 3: Wie man Fehlermeldungen und Codes zurückgibt

Betrachten Sie die HTTP-Statuscodes 4xx oder 5xx als Fehlerkategorien. Sie können den Fehler im Textkörper näher erläutern.

Verbindung zur Datenbank fehlgeschlagen: / Falsches Datenbank-Login : Im Allgemeinen sollten Sie für diese Art von Fehlern einen 500-Fehler verwenden. Dies ist ein serverseitiger Fehler. Der Client hat nichts falsch gemacht. 500-Fehler werden normalerweise als "wiederholbar" betrachtet, d.h. der Client kann die gleiche Anfrage wiederholen und erwarten, dass sie erfolgreich ist, sobald die Probleme des Servers behoben sind. Geben Sie die Details im Textkörper an, so dass der Client uns Menschen einen gewissen Kontext liefern kann.

Die andere Fehlerkategorie ist die 4xx-Familie, die im Allgemeinen anzeigt, dass der Kunde etwas falsch gemacht hat. Diese Fehlerkategorie weist den Kunden normalerweise darauf hin, dass es nicht notwendig ist, die Anfrage in ihrer jetzigen Form zu wiederholen, da sie dauerhaft fehlschlagen wird. In diese Kategorie fallen zum Beispiel die Fehler "Ressource nicht gefunden" (HTTP 404) oder "Fehlerhafte Anfrage" (HTTP 400).


Punkt 4: Wie erfolgt die Authentifizierung?

Wie in Punkt 1 erwähnt, sollten Sie statt einer Benutzerauthentifizierung lieber eine Sitzung einrichten. Sie erhalten eine neue "Sitzungs-ID" zusammen mit dem entsprechenden HTTP-Statuscode (200: Zugriff gewährt oder 403: Zugriff verweigert) zurück.

Sie werden dann Ihren RESTful-Server fragen: "Kannst du mir die Ressource für diese Sitzungs-ID geben?".

Es gibt keinen authentifizierten Modus - REST ist zustandslos: Sie erstellen eine Sitzung, bitten den Server, Ihnen Ressourcen unter Verwendung dieser Sitzungs-ID als Parameter zur Verfügung zu stellen, und beim Abmelden wird die Sitzung gelöscht oder läuft ab.

0 Stimmen

Die Erläuterung von POST ist falsch; formal gesehen hängt die Funktion von POST von dem Dokument ab, das Sie senden. Die einzige wirkliche Anforderung ist, dass es nicht idempotent sein muss, was wiederum bedeutet, dass es nicht wiederholbare Aktionen wie das Ausstellen neuer IDs durchführen kann. (Create entspricht POST, aber das ist nur eine Teilmenge dessen, was POST tun kann.) Ähnlich verhält es sich mit PUT Mai Ressourcen mit benutzerdefinierten IDs erstellen; so funktioniert WebDAV

11 Stimmen

Sehr gut, aber Ihre Verwendung von PUT um ein Passwort zu ändern, ist wahrscheinlich falsch; PUT erfordert die gesamte Ressource, so dass man alle Benutzerattribute senden müsste, um HTTP (und damit HATEOAS REST) zu entsprechen. Stattdessen sollte man zum Ändern des Kennworts einfach Folgendes verwenden PATCH ou POST .

1 Stimmen

Ich denke, dass dieser Beitrag perfekt wäre, wenn Sie mehr darüber schreiben würden, was "POST: Behandelt das adressierte Mitglied als eigenständige Sammlung und erstellt eine neue, ihr untergeordnete Sammlung". - Ich habe durch Googeln herausgefunden, was es bedeutet - es ist eine Ausnahme von Ihrer ansonsten großartigen Antwort.

82voto

Will Hartung Punkte 110997

Einfach ausgedrückt: Sie machen das völlig verkehrt.

Sie sollten dies nicht unter dem Gesichtspunkt betrachten, welche URLs Sie verwenden sollten. Die URLs gibt es im Grunde "umsonst", sobald Sie entschieden haben, welche Ressourcen für Ihr System notwendig sind UND wie Sie diese Ressourcen und die Interaktionen zwischen den Ressourcen und dem Anwendungsstatus darstellen werden.

Um zu zitieren Roy Fielding

Eine REST-API sollte fast die ganze Zeit über Beschreibungsaufwand auf die Definition der Medientyp(en), die für die Darstellung von Ressourcen und zur Steuerung des Anwendungs Anwendungsstatus verwendet werden, oder in der Definition von erweiterten Beziehungsnamen und/oder Hypertext-fähigen Markup für bestehende Standard-Medientypen. Jeder Aufwand für zu beschreiben, welche Methoden für welche URIs von Interesse verwendet werden sollen, sollte vollständig im Rahmen der Verarbeitungsregeln Verarbeitungsregeln für einen Medientyp (und in den meisten Fällen bereits definiert durch bestehende Medientypen). [Versagen bedeutet hier, dass Out-of-Band Informationen die Interaktion steuern anstelle von Hypertext.]

Die Leute fangen immer mit den URIs an und denken, dass dies die Lösung ist, und dann neigen sie dazu, ein Schlüsselkonzept in der REST-Architektur zu übersehen, insbesondere, wie oben zitiert, "Versagen bedeutet hier, dass Out-of-Band-Informationen die Interaktion steuern, anstatt Hypertext."

Um ehrlich zu sein, sehen viele einen Haufen URIs und einige GETs und PUTs und POSTs und denken, REST sei einfach. REST ist nicht einfach. RPC über HTTP ist einfach, das Hin- und Herschieben von Datenpaketen über HTTP-Payloads ist einfach. REST geht jedoch darüber hinaus. REST ist protokollunabhängig. HTTP ist einfach sehr beliebt und eignet sich gut für REST-Systeme.

REST lebt von den Medientypen, ihren Definitionen und der Art und Weise, wie die Anwendung die für diese Ressourcen verfügbaren Aktionen über Hypertext (Links, effektiv) steuert.

Es gibt verschiedene Ansichten über Medientypen in REST-Systemen. Einige bevorzugen anwendungsspezifische Nutzdaten, während andere die vorhandenen Medientypen in Rollen umwandeln, die für die Anwendung geeignet sind. Einerseits gibt es beispielsweise spezifische XML-Schemata, die für Ihre Anwendung geeignet sind, und andererseits die Verwendung von XHTML als Darstellung, vielleicht durch Mikroformate und andere Mechanismen.

Ich denke, dass beide Ansätze ihre Berechtigung haben, wobei XHTML sehr gut in Szenarien funktioniert, die sowohl das menschengesteuerte als auch das maschinengesteuerte Web überschneiden, während die ersteren, spezifischeren Datentypen meiner Meinung nach besser die Interaktion zwischen Maschinen erleichtern. Ich finde, dass die Aufwertung von Standardformaten die Aushandlung von Inhalten potenziell schwierig machen kann. "application/xml+yourresource" ist als Medientyp viel spezifischer als "application/xhtml+xml", da letzteres auf viele Nutzdaten zutreffen kann, die für einen Maschinen-Client von Interesse sein können oder auch nicht, und die er auch nicht ohne Introspektion bestimmen kann.

XHTML funktioniert jedoch (natürlich) sehr gut im menschlichen Web, wo Webbrowser und Rendering sehr wichtig sind.

Ihre Bewerbung wird Sie bei solchen Entscheidungen unterstützen.

Ein Teil des Entwurfsprozesses eines REST-Systems besteht darin, die erstklassigen Ressourcen in Ihrem System zu ermitteln, zusammen mit den abgeleiteten Ressourcen, die zur Unterstützung der Operationen auf den primären Ressourcen erforderlich sind. Sobald die Ressourcen entdeckt sind, ist die Darstellung dieser Ressourcen sowie die Zustandsdiagramme, die den Ressourcenfluss über Hypertext innerhalb der Darstellungen zeigen, die nächste Herausforderung.

Es sei daran erinnert, dass jede Darstellung einer Ressource in einem Hypertextsystem sowohl die eigentliche Ressourcendarstellung als auch die für die Ressource verfügbaren Zustandsübergänge kombiniert. Betrachten Sie jede Ressource als Knoten in einem Graphen, wobei die Links die Linien sind, die von diesem Knoten zu anderen Zuständen führen. Diese Links informieren die Kunden nicht nur darüber, was getan werden kann, sondern auch darüber, was dafür erforderlich ist (da ein guter Link den URI und den erforderlichen Medientyp kombiniert).

Zum Beispiel können Sie haben:

<link href="http://example.com/users" rel="users" type="application/xml+usercollection"/>
<link href="http://example.com/users?search" rel="search" type="application/xml+usersearchcriteria"/>

In Ihrer Dokumentation ist von einem rel-Feld mit dem Namen "users" und dem Medientyp "application/xml+youruser" die Rede.

Diese Links mögen überflüssig erscheinen, da sie alle auf dieselbe URI verweisen, sozusagen. Aber das sind sie nicht.

Der Grund dafür ist, dass der Link für die Beziehung "Benutzer" die Sammlung von Benutzern betrifft, und Sie können die einheitliche Schnittstelle verwenden, um mit der Sammlung zu arbeiten (GET, um alle Benutzer abzurufen, DELETE, um alle Benutzer zu löschen usw.).

Wenn Sie an diese URL POSTen, müssen Sie ein "application/xml+usercollection"-Dokument übergeben, das wahrscheinlich nur eine einzige Benutzerinstanz innerhalb des Dokuments enthält, so dass Sie den Benutzer hinzufügen können, oder vielleicht auch nicht, um mehrere auf einmal hinzuzufügen. Vielleicht schlägt Ihre Dokumentation vor, dass Sie anstelle der Sammlung einfach einen einzelnen Benutzertyp übergeben können.

Sie können sehen, was die Anwendung benötigt, um eine Suche durchzuführen, wie durch den Link "Suche" und seinen Medientyp definiert. In der Dokumentation für den Medientyp "Suche" erfahren Sie, wie sich dies verhält und was Sie als Ergebnis erwarten können.

Die URIs selbst sind jedoch im Grunde genommen unwichtig. Die Anwendung hat die Kontrolle über die URIs, nicht die Clients. Abgesehen von einigen wenigen "Einstiegspunkten" sollten sich Ihre Clients bei ihrer Arbeit auf die von der Anwendung bereitgestellten URIs verlassen.

Der Kunde muss wissen, wie er die Medientypen manipulieren und interpretieren kann, aber er muss sich nicht unbedingt darum kümmern, wohin die Daten gehen.

Diese beiden Links sind in den Augen des Kunden semantisch identisch:

<link href="http://example.com/users?search" rel="search" type="application/xml+usersearchcriteria"/>
<link href="http://example.com/AW163FH87SGV" rel="search" type="application/xml+usersearchcriteria"/>

Konzentrieren Sie sich also auf Ihre Ressourcen. Konzentrieren Sie sich auf ihre Zustandsübergänge in der Anwendung und darauf, wie dies am besten erreicht werden kann.

2 Stimmen

Vielen Dank, Will, für diese sehr ausführliche Antwort. Ich habe mehrere Punkte verstanden. Mir ist klar, dass die Planung von "wie die URL aussieht" genau umgekehrt ist, und ich plane auch von der Ressourcenseite her. Wenn ich URLs habe, mit denen ich spielen kann, fällt es mir leichter, das Konzept zu verstehen. Es könnte dass meine Anforderungen mit einem System erfüllt werden können, das nicht zu 100 % den REST-Prinzipien folgt, wie Sie sie hier definieren. Ich werde eine vollständige Liste der Anforderungen für jeden Ressourcentyp erstellen, dann werde ich wohl eine Entscheidung treffen können. Prost.

32voto

Stefan Tilkov Punkte 1662

zu 1 : Das sieht soweit gut aus. Denken Sie daran, den URI des neu angelegten Benutzers in einem "Location:"-Header als Teil der Antwort auf POST zusammen mit einem "201 Created"-Statuscode zurückzugeben.

zu 2 : Die Aktivierung über GET ist eine schlechte Idee, und die Aufnahme des Verbs in den URI ist ein Designfehler. Sie sollten in Erwägung ziehen, bei einem GET ein Formular zurückzugeben. In einer Webanwendung wäre dies ein HTML-Formular mit einer Submit-Schaltfläche; im API-Nutzungsfall könnten Sie eine Darstellung zurückgeben, die einen URI enthält, der zur Aktivierung des Kontos mit PUT eingegeben werden muss. Natürlich können Sie diese URI auch in die Antwort auf POST an /users aufnehmen. Die Verwendung von PUT stellt sicher, dass Ihre Anfrage idempotent ist, d. h. sie kann sicher erneut gesendet werden, wenn der Client nicht sicher ist, ob sie erfolgreich ist. Überlegen Sie generell, in welche Ressourcen Sie Ihre Verben verwandeln können (eine Art "Substantivierung der Verben"). Fragen Sie sich, mit welcher Methode Ihre spezifische Aktion am ehesten übereinstimmt. Z.B. change_password -> PUT; deactivate -> wahrscheinlich DELETE; add_credit -> möglicherweise POST oder PUT. Verweisen Sie den Client auf die entsprechenden URIs, indem Sie sie in Ihre Darstellungen aufnehmen.

zu 3. Erfinden Sie keine neuen Statuscodes, es sei denn, Sie glauben, dass sie so allgemein sind, dass sie es verdienen, weltweit standardisiert zu werden. Bemühen Sie sich, den am besten geeigneten Statuscode zu verwenden (lesen Sie über alle in RFC 2616). Fügen Sie zusätzliche Informationen in den Antwortkörper ein. Wenn Sie sich wirklich sicher sind, dass Sie einen neuen Statuscode erfinden wollen, denken Sie noch einmal darüber nach; wenn Sie das immer noch glauben, stellen Sie sicher, dass Sie zumindest die richtige Kategorie wählen (1xx -> OK, 2xx -> informational, 3xx -> redirection; 4xx-> client error, 5xx -> server error). Habe ich schon erwähnt, dass es eine schlechte Idee ist, neue Statuscodes zu erfinden?

zu 4. Verwenden Sie, wenn möglich, den in HTTP integrierten Authentifizierungsrahmen. Sehen Sie sich an, wie Google die Authentifizierung in GData durchführt. Im Allgemeinen sollten Sie keine API-Schlüssel in Ihre URIs einfügen. Versuchen Sie, Sitzungen zu vermeiden, um die Skalierbarkeit zu verbessern und das Caching zu unterstützen - wenn sich die Antwort auf eine Anfrage aufgrund eines früheren Ereignisses unterscheidet, haben Sie sich in der Regel an eine bestimmte Serverprozessinstanz gebunden. Es ist viel besser, den Sitzungsstatus entweder in einen Client-Status umzuwandeln (z. B. in einen Teil nachfolgender Anfragen) oder ihn explizit zu machen, indem man ihn in einen (Server-)Ressourcenzustand umwandelt, d. h. ihm eine eigene URI gibt.

0 Stimmen

Können Sie erläutern, warum man API-Schlüssel nicht in URLs einfügen sollte? Liegt es daran, dass sie in Proxy-Protokollen sichtbar sind? Was ist, wenn die Schlüssel flüchtig und zeitbasiert sind? Was ist, wenn HTTPS verwendet wird?

4 Stimmen

Abgesehen davon, dass dies gegen den Geist verstößt (URIs sollten Dinge identifizieren), besteht die Hauptfolge darin, dass es das Caching ruiniert.

23voto

friedo Punkte 64178

1. Sie haben die richtige Vorstellung davon, wie Sie Ihre Ressourcen gestalten sollten, IMHO. Ich würde nichts ändern.

2. Anstatt zu versuchen, HTTP um weitere Verben zu erweitern, sollten Sie überlegen, worauf sich die von Ihnen vorgeschlagenen Verben im Hinblick auf die grundlegenden HTTP-Methoden und -Ressourcen reduzieren lassen. Zum Beispiel, statt einer activate_login verb, könnten Sie Ressourcen wie: /api/users/1/login/active was ein einfacher Boolescher Wert ist. Um eine Anmeldung zu aktivieren, brauchen Sie nur PUT ein Dokument, in dem 'true' oder 1 oder was auch immer steht. Zum Deaktivieren, PUT ein Dokument, das leer ist oder 0 oder false enthält.

Um Passwörter zu ändern oder festzulegen, führen Sie einfach folgende Schritte aus PUT s zu /api/users/1/password .

Wann immer Sie etwas hinzufügen müssen (z. B. einen Kredit), denken Sie an POST s. Sie könnten zum Beispiel eine POST auf eine Ressource wie /api/users/1/credits mit einem Textkörper, der die Anzahl der hinzuzufügenden Credits enthält. A PUT auf dieselbe Ressource könnte verwendet werden, um den Wert zu überschreiben, anstatt ihn hinzuzufügen. A POST mit einer negativen Zahl im Körper würde subtrahiert werden und so weiter.

3. Ich würde dringend davon abraten, die grundlegenden HTTP-Statuscodes zu erweitern. Wenn Sie keinen finden, der genau zu Ihrer Situation passt, wählen Sie den nächstliegenden und fügen Sie die Fehlerdetails in den Antwortkörper ein. Denken Sie auch daran, dass HTTP-Header erweiterbar sind; Ihre Anwendung kann alle benutzerdefinierten Header definieren, die Sie möchten. Eine Anwendung, an der ich gearbeitet habe, konnte zum Beispiel einen 404 Not Found unter verschiedenen Umständen. Anstatt den Client zu veranlassen, den Antwortkörper nach dem Grund zu durchsuchen, haben wir einfach eine neue Kopfzeile hinzugefügt, X-Status-Extended die unsere proprietären Statuscode-Erweiterungen enthielten. Sie könnten also eine Antwort wie diese sehen:

HTTP/1.1 404 Not Found    
X-Status-Extended: 404.3 More Specific Error Here

Auf diese Weise weiß ein HTTP-Client wie ein Webbrowser immer noch, was mit dem regulären 404-Code zu tun ist, und ein anspruchsvollerer HTTP-Client kann wählen, ob er sich den X-Status-Extended Kopfzeile für genauere Informationen.

4. Für die Authentifizierung empfehle ich, wenn möglich, die HTTP-Authentifizierung zu verwenden. Aber IMHO spricht nichts dagegen, eine Cookie-basierte Authentifizierung zu verwenden, wenn das für Sie einfacher ist.

4 Stimmen

Nette Idee, "erweiterte" Ressourcen zu verwenden, um kleinere Teile einer größeren Ressource zu bearbeiten.

1 Stimmen

Cookies sind in HTTP/REST gültig, aber der Server sollte das Cookie nicht als Zustand (also nicht als Sitzung) speichern. Das Cookie kann jedoch einen Wert wie einen HMAC speichern, der zerlegt werden kann, ohne dass der Status an anderer Stelle nachgeschlagen werden muss.

15voto

inf3rno Punkte 22107

REST-Grundlagen

REST hat eine einheitliche Schnittstellenbeschränkung, die besagt, dass sich der REST-Client auf Standards und nicht auf anwendungsspezifische Details des eigentlichen REST-Dienstes stützen muss, so dass der REST-Client nicht durch geringfügige Änderungen beschädigt wird und wahrscheinlich wiederverwendbar ist.

Es besteht also ein Vertrag zwischen dem REST-Client und dem REST-Dienst. Wenn Sie HTTP als zugrunde liegendes Protokoll verwenden, sind die folgenden Standards Teil des Vertrags:

  • HTTP 1.1
  • Methodendefinitionen
  • Statuscode-Definitionen
  • Cache-Kontroll-Header
  • accept und content-type Kopfzeilen
  • Autorisierungskopfzeilen
  • IRI (utf8 URI )
  • Körper (wählen Sie einen aus)
  • registrierter anwendungsspezifischer MIME-Typ, z. B. Labyrinth+xml
  • herstellerspezifischer MIME-Typ, z. B. vnd.github+json
  • generischer MIME-Typ mit
    • Anwendungsspezifisches RDF-Vokabular, z. B. ld+json & hydra , schema.org
    • anwendungsspezifisches Profil, z. B. hal+json & Profil-Link param (nehme ich an)
  • Hyperlinks
    • was sie enthalten sollten (wählen Sie eines aus)
      • Einsendung Link-Kopfzeilen
      • Senden einer Hypermedia-Antwort, z.B. html, atom+xml, hal+json, ld+json&hydra, usw...
    • Semantik
      • IANA-Link-Relationen und wahrscheinlich benutzerdefinierte Link-Relationen verwenden
      • ein anwendungsspezifisches RDF-Vokabular verwenden

REST hat eine zustandslose Einschränkung, die besagt, dass die Kommunikation zwischen dem REST-Dienst und dem Client zustandslos sein muss. Dies bedeutet, dass der REST-Dienst die Client-Zustände nicht aufrechterhalten kann, so dass Sie keinen serverseitigen Sitzungsspeicher haben können. Sie müssen jede einzelne Anfrage authentifizieren. So ist z. B. HTTP basic auth (Teil des HTTP-Standards) in Ordnung, da es den Benutzernamen und das Kennwort bei jeder Anfrage sendet.

Um Ihre Fragen zu beantworten

  1. Ja, das kann es sein.

Die Kunden interessieren sich nicht für die IRI-Struktur, sondern für die Semantik, da sie Links mit Link-Relationen oder Linked-Data-Attributen (RDF) folgen.

Das Einzige, was bei den IRIs wichtig ist, ist, dass ein einzelner IRI nur eine einzige Ressource identifizieren darf. Es ist erlaubt, dass eine einzelne Ressource, wie ein Benutzer, viele verschiedene IRIs hat.

Es ist ziemlich einfach, warum wir schöne IRIs wie /users/123/password Es ist viel einfacher, die Routing-Logik auf dem Server zu schreiben, wenn man den IRI einfach durch Lesen versteht.

  1. Sie haben mehr Verben, wie PUT, PATCH, OPTIONS und noch mehr, aber Sie brauchen nicht mehr davon... Anstatt neue Verben hinzuzufügen, müssen Sie lernen, wie man neue Ressourcen hinzufügt.

    deactivate_login -> PUT /login/active false change_password -> PUT /user/xy/password "newpass" add_credit -> POST /credit/raise {details: {}}

(Die Anmeldung ist aus der REST-Perspektive wegen der zustandslosen Beschränkung nicht sinnvoll).

  1. Ihren Benutzern ist es egal, warum das Problem besteht. Sie wollen nur wissen, ob es einen Erfolg oder einen Fehler gibt, und wahrscheinlich eine Fehlermeldung, die sie verstehen können, zum Beispiel: "Es tut uns leid, aber wir konnten Ihren Beitrag nicht speichern", usw...

Die HTTP-Status-Header sind Ihre Standard-Header. Alles andere sollte im Body stehen, denke ich. Ein einziger Header reicht nicht aus, um zum Beispiel detaillierte mehrsprachige Fehlermeldungen zu beschreiben.

  1. Die zustandslose Beschränkung (zusammen mit den Cache- und Schichtsystem-Beschränkungen) stellt sicher, dass der Dienst gut skalierbar ist. Sie wollen sicher nicht Millionen von Sitzungen auf dem Server verwalten, wenn Sie das Gleiche auf den Clients tun können...

    Der 3rd-Party-Client erhält ein Zugriffstoken, wenn der Benutzer ihm über den Haupt-Client Zugriff gewährt. Danach sendet der Drittanbieter-Client das Zugriffstoken mit jeder Anfrage. Es gibt kompliziertere Lösungen, z. B. können Sie jede einzelne Anfrage signieren usw. Weitere Einzelheiten finden Sie im OAuth-Handbuch.

Verwandte Literatur

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X