it-swarm.com.de

REST API DESIGN - Eine Ressource über REST mit verschiedenen Parametern aber demselben URL-Muster erhalten

Ich habe eine Frage zum REST URL-Design. Ich habe hier einige relevante Beiträge gefunden: Verschiedene REST-konforme Darstellungen derselben Ressource und hier: REST-konforme URL zum Abrufen der Ressource nach verschiedenen Feldern aber die Antworten sind nicht ganz klar, welche die besten sind Praktiken sind und warum. Hier ist ein Beispiel.

Ich habe REST URLs, um die Ressource "Benutzer" darzustellen. Ich kann einen Benutzer mit einer ID oder einer E-Mail-Adresse abrufen, aber die URL-Darstellung bleibt für beide gleich. Beim Durchgehen vieler Blogs und Bücher sehe ich, dass die Leute dies auf viele verschiedene Arten getan haben. Beispielsweise

lies diese Übung in einem Buch und irgendwo auf Stackoverflow (ich finde den Link nicht wieder)

GET /users/id={id}
GET /users/email={email}

lesen Sie diese Praxis in vielen Blogs

GET /users/{id}
GET /users/email/{email}

Abfrageparameter werden normalerweise zum Filtern der Ergebnisse der durch die URL dargestellten Ressourcen verwendet, aber ich habe gesehen, dass diese Vorgehensweise ebenfalls angewendet wird

GET /users?id={id}
GET /users?email={email}

Meine Frage ist, welche dieser Praktiken für Entwickler, die die APIs konsumieren, am sinnvollsten ist und warum? Ich glaube, es gibt keine in Stein gemeißelten Regeln, wenn es um REST URL-Designs und Namenskonventionen geht, aber ich wollte nur wissen, welchen Weg ich einschlagen sollte, um Entwicklern zu helfen, die API besser zu verstehen.

Alle Hilfe dankbar!

64
shahshi15

Durch meine Erfahrung, GET /users/{id} GET /users/email/{email} ist der gebräuchlichste Ansatz. Ich würde auch erwarten, dass die Methoden 404 Not Found zurückgeben, wenn ein Benutzer mit dem angegebenen id oder email nicht existiert. Ich wäre nicht überrascht zu sehen, GET /users/id/{id}, entweder (obwohl es meiner Meinung nach überflüssig ist).

Kommentare zu den anderen Ansätzen

  1. GET /users/id={id} GET /users/email={email}
    • Ich glaube nicht, dass ich das gesehen habe, und wenn ich es gesehen hätte, wäre es sehr verwirrend. Es ist fast so, als würde versucht, Abfrageparameter mit Pfadparametern zu imitieren.
  2. GET /users?id={id} GET /users?email={email}
    • Ich denke, Sie haben den Nagel auf den Kopf getroffen, als Sie die Verwendung von Abfrageparametern zum Filtern erwähnt haben.
    • Wäre es jemals sinnvoll, diese Ressource mit sowohl einem id als auch einem email (z. B. GET /users?id={id}&email={email})? Wenn nicht, würde ich keine einzige Ressourcenmethode wie diese verwenden.
    • Ich würde diese Methode zum Abrufen einer Liste von Benutzern mit optionalen Abfrageparametern zum Filtern erwarten, aber ich würde nicht erwarten, dass id, email oder ein beliebiger eindeutiger Bezeichner, der zu den Parametern gehört. Beispielsweise: GET /users?status=BANNED gibt möglicherweise eine Liste der gesperrten Benutzer zurück.

Schauen Sie sich diese Antwort von einer verwandten Frage an.

81
DannyMo

Wenn Sie dies pragmatisch betrachten, haben Sie eine Sammlung von Benutzern:

/users   # this returns many

Jeder Benutzer verfügt über einen dedizierten Ressourcenspeicherort:

/users/{id}    # this returns one

Sie haben auch verschiedene Möglichkeiten, nach Benutzern zu suchen:

/users?email={email}
/users?name=*bob*

Da dies alle Abfrageparameter für/users sind, sollten sie alle Listen zurückgeben, auch wenn es sich um eine Liste mit 1 handelt.

Ich habe hier einen Blog-Beitrag über pragmatisches RESTful API-Design geschrieben, der unter anderem hier darüber spricht: http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api

32
Vinay Sahni

Über die Benutzerressourcen

auf dem Pfad /users wird immer eine Sammlungsressource zurückgegeben.

auf dem Pfad /users/[user_id] erhalten Sie eine Singleton-Ressource, die den Benutzer mit seiner ID [user_id] darstellt, oder alternativ eine 404-Antwort, wenn kein Benutzer mit der angeforderten [user_id] vorhanden ist (oder verboten (401), wenn Sie nicht berechtigt sind um auf die angeforderte Benutzerressource zuzugreifen, etc). Jeder Ressourcenpfad hat nur eine einzige Kennung, mit der Sie die Ressourcen finden/identifizieren können. Es ist nicht möglich, mehrere Bezeichner für dieselbe Ressource im selben Ressourcenpfad zu verwenden. Wenn Sie eine Ressource in einer Antwort zurückerhalten, wird dieser Bezeichner als Self-HREF in die Antwort aufgenommen, um die Ressource zu lokalisieren/zu identifizieren.

Sie können den Pfad /users Mit GET/query-Parametern abfragen. Dadurch wird eine Sammlung mit Benutzern zurückgegeben, die die angeforderten Kriterien erfüllen. Die zurückgegebene Auflistung enthält die Benutzerressourcen mit ihrer identifizierenden Self-HREF.

Über die E-Mail-Ressourcen

Wenn ich mir ansehe, was Sie für eine E-Mail vorgeschlagen haben, würde ich eher Folgendes denken:

E-Mails von Benutzern sind ebenfalls Ressourcen. Ich würde also denken, dass /users/[user_id]/emails Eine Sammlung von E-Mail-Adressen für Benutzer mit der ID user_id Zurückgibt. /users/[user_id]/emails/[email_id] Gibt die E-Mail des Benutzers mit user_id und ['email_id'] zurück. Was Sie als Bezeichner verwenden, liegt bei Ihnen, aber ich würde mich an eine ganze Zahl halten. Sie können eine E-Mail vom Benutzer löschen, indem Sie eine DELETE -Anforderung an den Pfad senden, der die zu löschende E-Mail identifiziert. Zum Beispiel löscht DELETE auf /users/[user_id]/emails/[email_id] Die E-Mail mit der E-Mail-ID, die dem Benutzer mit der Benutzer-ID gehört. Höchstwahrscheinlich darf nur dieser Benutzer diesen Löschvorgang ausführen. Andere Benutzer erhalten eine Antwort 401.

Wenn ein Benutzer nur eine E-Mail-Adresse haben kann, können Sie sich an /users/[user_id]/email Halten. Dies gibt eine Singleton-Ressource zurück. Der Benutzer kann seine E-Mail-Adresse aktualisieren, indem er PUTting oder POSTing eine neue E-Mail-Adresse unter dieser URL eingibt. Wenn Sie in Ihrer Anwendung Benutzern ohne E-Mail nicht erlauben, sollten Sie mit einem 401 antworten, wenn er eine DELETE -Anforderung an diese URL sendet.

2
Wilt