Ich entwarf eine Web-App und überlegte dann, wie meine API als RESTful-Webdienst gestaltet werden sollte. Derzeit sind die meisten meiner URIs generisch und gelten möglicherweise für verschiedene Web-Apps:
GET /logout // destroys session and redirects to /
GET /login // gets the webpage that has the login form
POST /login // authenticates credentials against database and either redirects home with a new session or redirects back to /login
GET /register // gets the webpage that has the registration form
POST /register // records the entered information into database as a new /user/xxx
GET /user/xxx // gets and renders current user data in a profile view
POST /user/xxx // updates new information about user
Ich habe das Gefühl, dass ich hier viel falsch mache, nachdem ich mich in SO und google umgesehen habe.
Beginnend mit /logout
, Vielleicht, weil ich nicht wirklich GET
irgendetwas - es ist angemessener, POST
eine Anfrage nach /logout
Zu senden, um die Sitzung zu zerstören, und dann GET
die Umleitung. Und sollte der Begriff /logout
Bleiben?
Was ist mit /login
Und /register
? Ich könnte /register
In /registration
Ändern, aber das ändert nichts an der grundsätzlichen Funktionsweise meines Dienstes - wenn es tiefere Probleme gibt.
Ich stelle jetzt fest, dass ich niemals eine /user
- Ressource verfügbar mache. Vielleicht könnte das irgendwie genutzt werden. Nehmen Sie zum Beispiel den Benutzer myUser
:
foo.com/user/myUser
oder
foo.com/user
Der Endbenutzer benötigt diese zusätzliche Ausführlichkeit in der URI nicht. Doch welches ist optisch ansprechender?
Ich habe hier auf SO= über dieses REST) Geschäft einige andere Fragen bemerkt, aber ich würde mich sehr über eine Anleitung darüber freuen, was ich hier wenn möglich dargelegt habe.
Vielen Dank!
PDATE:
Ich möchte auch einige Meinungen über:
/user/1
vs
/user/myUserName
Eine Sache sticht insbesondere als nicht REST-voll heraus: die Verwendung einer GET-Anfrage zum Abmelden.
(von http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Safe_methods )
Einige Methoden (z. B. HEAD, GET, OPTIONS und TRACE) sind als sicher definiert. Dies bedeutet, dass sie nur zum Abrufen von Informationen dienen und den Status des Servers nicht ändern dürfen. Mit anderen Worten, sie sollten keine Nebenwirkungen haben, die über relativ harmlose Effekte wie Protokollierung, Zwischenspeichern, Anzeigenschaltung von Bannern oder Inkrementieren eines Webzählers hinausgehen. [...]
[... H] andling [von GET-Anfragen] durch den Server unterliegt keinerlei technischen Einschränkungen. Daher kann eine unachtsame oder absichtliche Programmierung nicht unbedeutende Änderungen auf dem Server verursachen. Dies wird nicht empfohlen, da dies zu Problemen beim Web-Caching, bei Suchmaschinen und anderen automatisierten Agenten führen kann [...]
Zum Abmelden und Umleiten können Sie einen Beitrag zu Ihrem Abmelde-URI senden, der eine 303-Antwort auf die Seite nach dem Abmelden weiterleitet.
http://en.wikipedia.org/wiki/Post/Redirect/Get
http://en.wikipedia.org/wiki/HTTP_3
Bearbeiten, um Bedenken hinsichtlich des URL-Designs auszuräumen:
"Wie gestalte ich meine Ressourcen?" ist eine wichtige Frage für mich; "Wie gestalte ich meine URLs?" ist eine Überlegung in zwei Bereichen:
URLs, die den Benutzern angezeigt werden, sollten nach Möglichkeit nicht zu hässlich und aussagekräftig sein. Wenn Sie möchten, dass Cookies in Anfragen an eine Ressource gesendet werden, aber nicht an andere, müssen Sie Ihre Pfade und Cookie-Pfade strukturieren.
Wenn JRandomUser
sein eigenes Profil anzeigen möchte und Sie möchten, dass die URL hübscher als foo.com/user/JRandomUser
Oder foo.com/user/(JRandom's numeric user id here)
ist, können Sie eine separate URL erstellen, die nur einem Benutzer angezeigt wird auf ihre eigenen informationen:
GET foo.com/profile /*examines cookies to figure out who
* is logged in (SomeUser) and then
* displays the same response as a
* GET to foo.com/users/SomeUser.
*/
Ich würde Unwissenheit viel eher als Weisheit zu diesem Thema behaupten, aber hier sind einige Überlegungen zum Ressourcendesign:
RESTful kann als Richtlinie zum Erstellen von URLs verwendet werden, und Sie können sessions und sers Ressourcen erstellen:
GET /session/new
Ruft die Webseite mit dem Anmeldeformular aufPOST /session
Authentifiziert Anmeldeinformationen für die DatenbankDELETE /session
Zerstört die Sitzung und leitet zu/weiterGET /users/new
Ruft die Webseite mit dem Registrierungsformular aufPOST /users
Zeichnet die eingegebenen Informationen als new/user/xxx in der Datenbank aufGET /users/xxx
// holt und rendert aktuelle Benutzerdaten in einer ProfilansichtPOST /users/xxx
// aktualisiert neue Informationen zum BenutzerDiese können im Plural oder im Singular sein (ich bin mir nicht sicher, welches richtig ist). Ich habe normalerweise /users
Für eine Benutzerindexseite (wie erwartet) und /sessions
Verwendet, um zu sehen, wer (wie erwartet) angemeldet ist.
Die Verwendung des Namens in der URL anstelle einer Zahl (/users/43
Vs. /users/joe
) Wird normalerweise von dem Wunsch getrieben, den Benutzern oder Suchmaschinen freundlicher zu sein, und nicht von technischen Anforderungen. Beides ist in Ordnung, aber ich würde empfehlen, dass Sie konsequent sind.
Ich denke, wenn Sie mit dem Register/Login/Logout oder sign(in|up|out)
gehen, funktioniert es nicht so gut mit der Restful-Terminologie.
Sitzungen sind nicht RESTful
Ja, ich weiß. Es wird normalerweise mit OAuth gemacht, aber wirklich sind Sitzungen nicht RESTful. Sie sollten keine/login/logout-Ressource haben, da Sie keine Sitzungen haben sollten.
Wenn Sie es tun wollen, machen Sie es RUHIG. Ressourcen sind Substantive und/login und/logout sind keine Substantive. Ich würde mit/Sitzung gehen. Dadurch wird das Erstellen und Löschen natürlicher.
POST vs. GET für Sitzungen ist einfach. Wenn Sie Benutzer/Kennwort als Variablen senden, würde ich POST verwenden, da ich das Kennwort nicht als Teil der URI senden lassen möchte. Es wird in Protokollen angezeigt und möglicherweise angezeigt Sie laufen auch Gefahr, dass Software aufgrund von GET-Einschränkungen ausfällt.
Ich verwende im Allgemeinen Basic Auth oder kein Auth mit REST Services.
Benutzer anlegen
Es ist eine Ressource, daher sollten Sie sich nicht registrieren müssen.
Welche Art von ID zu verwenden ist, ist eine schwierige Frage. Sie müssen darüber nachdenken, Eindeutigkeit zu erzwingen und alte IDs, die DELETEd waren, wiederzuverwenden. Beispielsweise möchten Sie diese IDs nicht als Fremdschlüssel in einem Backend verwenden, wenn IDs wiederverwendet werden sollen (sofern dies überhaupt möglich ist). Sie können jedoch nach einer externen/internen ID-Konvertierung suchen, um die Backend-Anforderungen zu verringern.
Ich spreche einfach aus meiner Erfahrung mit der Integration verschiedener REST Web Services für meine Kunden, sei es für mobile Apps oder für die Server-zu-Server-Kommunikation sowie für die Erstellung von REST APIs für Andere. Hier sind einige Beobachtungen, die ich aus der API REST anderer Personen sowie aus den von uns selbst erstellten gesammelt habe:
GET/register // ruft die Webseite mit dem Registrierungsformular auf
GET/logout // löscht die Sitzung und leitet sie zu /[.____.)POST/login // authentifiziert die Anmeldeinformationen für die Datenbank und leitet sie entweder mit einer neuen Sitzung nach Hause weiter oder leitet sie zurück zu /login[.____]
Da REST als Dienste konzipiert sind, liefern Funktionen wie Anmelden und Abmelden normalerweise Erfolgs-/Fehlerergebnisse (normalerweise im JSON- oder XML-Datenformat), die dann vom Konsumenten interpretiert werden. Eine solche Interpretation könnte die von Ihnen erwähnte Weiterleitung zu einer geeigneten Webseite beinhalten
GET/register // ruft die Webseite mit dem Registrierungsformular auf POST/register // speichert die eingegebenen Informationen in der Datenbank als neues /user/xxx
Das sind einige Punkte aus dem, was ich behandelt habe. Ich hoffe, es hat Ihnen einige Einblicke verschafft.
Was die Implementierung Ihres REST angeht, sind dies die typischen Implementierungen, auf die ich gestoßen bin:
GET/logout
Führen Sie die Abmeldung im Backend aus und geben Sie JSON zurück, um den Erfolg/Misserfolg der Operation anzuzeigen
POST /login
Übermitteln Sie die Anmeldeinformationen an das Backend. Erfolg/Misserfolg zurückgeben. Bei Erfolg werden normalerweise auch das Sitzungstoken sowie die Profilinformationen zurückgegeben.
POST/register
Senden Sie die Registrierung an das Backend. Erfolg/Misserfolg zurückgeben. Wenn dies erfolgreich ist, wird dies normalerweise als erfolgreiche Anmeldung behandelt, oder Sie können die Registrierung als eigenständigen Dienst vornehmen
GET /user/xxx
Benutzerprofil abrufen und JSON-Datenformat für das Benutzerprofil zurückgeben
POST/user/xxx // umbenannt in POST /updateUser/xxx
Veröffentlichen Sie aktualisierte Profilinformationen im JSON-Format und aktualisieren Sie die Informationen im Backend. Rückgabe von Erfolg/Misserfolg an den Anrufer
Ich glaube, dies ist ein restvoller Ansatz zur Authentifizierung. Für LogIn verwenden Sie HttpPut
. Diese HTTP-Methode kann zur Erstellung verwendet werden, wenn der Schlüssel bereitgestellt wird. Wiederholte Anrufe sind idempotent. Für LogOff geben Sie denselben Pfad unter der Methode HttpDelete
an. Keine Verben verwendet. Ordnungsgemäße Pluralisierung von Sammlungen. Die HTTP-Methoden unterstützen den Zweck.
[HttpPut]
[Route("sessions/current")]
public IActionResult LogIn(LogInModel model) { ... }
[HttpDelete]
[Route("sessions/current")]
public IActionResult LogOff() { ... }
Falls gewünscht, können Sie aktiv durch Strom ersetzen.
Ich würde empfehlen, eine Benutzerkonto-URL zu verwenden, die der von Twitter ähnelt, wobei die Benutzerkonto-URL etwa foo.com/myUserName
so wie Sie mit der URL zu meinem Twitter-Account gelangen können https://Twitter.com/joelbyler
Ich bin nicht einverstanden, dass ich mich abmelden muss, wenn ich einen POST benötige. Wenn Sie als Teil Ihrer API eine Sitzung verwalten möchten, kann eine Sitzungs-ID in Form einer UUID verwendet werden, um den Überblick über einen Benutzer zu behalten und zu bestätigen, dass die ausgeführte Aktion autorisiert ist. Dann kann sogar ein GET die Sitzungs-ID an die Ressource übergeben.
Kurz gesagt, ich würde empfehlen, dass Sie es einfach halten, URLs sollten kurz und einprägsam sein.