it-swarm.com.de

REST Best Practices für APIs: Wo werden Parameter angegeben?

Eine REST -API kann auf mindestens zwei Arten Parameter haben:

  1. Als Teil des URL-Pfads (d. H. /api/resource/parametervalue)
  2. Als Abfrageargument (d. H. /api/resource?parameter=value)

Was ist hier die beste Praxis? Gibt es allgemeine Richtlinien für die Verwendung von 1 und für die Verwendung von 2?

Beispiel aus der Praxis: Twitter verwendet Abfrageparameter zum Angeben von Intervallen. (http://api.Twitter.com/1/statuses/home_timeline.json?since_id=12345&max_id=54321)

Wäre es besser, diese Parameter in den URL-Pfad aufzunehmen?

348

Wenn es dokumentierte Best Practices gibt, habe ich sie noch nicht gefunden. Hier sind jedoch einige Richtlinien, die ich verwende, um zu bestimmen, wo Parameter in einer URL abgelegt werden sollen:

Optionale Parameter sind in der Regel einfacher in die Abfragezeichenfolge einzufügen.

Wenn Sie einen 404-Fehler zurückgeben möchten, wenn der Parameterwert keiner vorhandenen Ressource entspricht, tendiere ich zu einem Pfadsegmentparameter. z.B. /customer/232 wobei 232 keine gültige Kunden-ID ist.

Wenn Sie jedoch eine leere Liste zurückgeben möchten und der Parameter nicht gefunden wird, empfehle ich die Verwendung von Abfragezeichenfolgenparametern. z.B. /contacts?name=dave

Wenn sich ein Parameter auf einen gesamten Unterbaum Ihres URI-Bereichs auswirkt, verwenden Sie ein Pfadsegment. z.B. ein Sprachparameter /en/document/foo.txt versus /document/foo.txt?language=en

Ich bevorzuge eindeutige Bezeichner in einem Pfadsegment anstelle eines Abfrageparameters.

Die offiziellen Regeln für URIs finden Sie in dieser RFC-Spezifikation hier . Es gibt auch eine andere sehr nützliche RFC-Spezifikation hier , die Regeln für die Parametrisierung von URIs definiert.

254
Darrel Miller

Späte Antwort, aber ich werde ein paar zusätzliche Erkenntnisse zu dem, was geteilt wurde, hinzufügen, nämlich dass es mehrere Arten von "Parametern" für eine Anfrage gibt, und Sie sollten dies berücksichtigen.

  1. Locators - z.B. Ressourcenkennungen wie IDs oder Aktion/Ansicht
  2. Filter - z.B. Parameter, die das Suchen, Sortieren oder Eingrenzen der Ergebnismenge ermöglichen.
  3. Zustand - z.B. Sitzungsidentifikation, API-Schlüssel, was auch immer.
  4. Inhalt - z. zu speichernde Daten.

Schauen wir uns nun die verschiedenen Stellen an, an denen diese Parameter gespeichert werden könnten.

  1. Header & Cookies anfordern
  2. URL-Abfragezeichenfolge ("GET" -Vars)
  3. URL-Pfade
  4. Body Query String/Multipart ("POST" -Vars)

Im Allgemeinen möchten Sie, dass der Status in Kopfzeilen oder Cookies festgelegt wird, je nachdem, um welche Art von Statusinformationen es sich handelt. Ich denke, wir können uns alle darauf einigen. Verwenden Sie bei Bedarf benutzerdefinierte HTTP-Header (X-My-Header).

Ebenso hat Content nur einen Zugehörigkeitsbereich, der sich im Anforderungshauptteil befindet, entweder als Abfragezeichenfolgen oder als http-Multipart- und/oder JSON-Content. Dies stimmt mit dem überein, was Sie vom Server erhalten, wenn dieser Ihnen Inhalte sendet. Sie sollten also nicht unhöflich sein und es anders machen.

Locators wie "id = 5" oder "action = refresh" oder "page = 2" sind als URL - Pfad sinnvoll, z. B. "_mysite.com/article/5/page=2_" Grundlagen wie Artikel und 5 bedeuten natürlich, dass ich die Daten vom Typ Artikel mit der ID 5) bekomme und zusätzliche Parameter als Teil der URI angegeben werden. Sie können die Form _page=2_ oder _page/2_ haben, wenn Sie wissen, dass die "Ordner" nach einem bestimmten Punkt in der URI Schlüsselwerte sind.

Filter werden immer in die Abfragezeichenfolge eingefügt, da sie zwar Teil der Suche nach den richtigen Daten sind, jedoch nur dazu dienen, eine Teilmenge oder eine Änderung dessen zurückzugeben, was die Locators alleine zurückgeben. Die Suche in _mysite.com/article/?query=Obama_ (Teilmenge) ist ein Filter, ebenso wie _/article/5?order=backwards_ (Modifikation). Überlegen Sie, was es tut, nicht nur, wie es heißt!

Wenn "view" das Ausgabeformat festlegt, handelt es sich um einen Filter (_mysite.com/article/5?view=pdf_), da er eine Änderung der gefundenen Ressource zurückgibt, anstatt nach der gewünschten Ressource zu suchen. Wenn es stattdessen entscheidet, welchen bestimmten Teil des Artikels wir sehen (_mysite.com/article/5/view=summary_), dann ist es ein Locator.

Denken Sie daran, Eingrenzen eine Reihe von Ressourcen filtert. Etwas Bestimmtes in einer Ressource zu finden heißt ... duh. Die Teilmengenfilterung kann eine beliebige Anzahl von Ergebnissen (sogar 0) zurückgeben. Beim Auffinden wird immer die bestimmte Instanz von etwas gefunden (falls vorhanden). Die Änderungsfilterung gibt die gleichen Daten wie der Locator zurück, außer geändert (sofern eine solche Änderung zulässig ist).

Hoffe, das hat den Leuten geholfen, ein paar Momente zu verbringen, wenn sie nicht mehr wissen, wo sie was abstellen sollen!

152
Tor Valamo

Es kommt auf ein Design an. Es gibt keine Regeln für URIs bei REST über HTTP (Hauptsache, sie sind eindeutig). Oft geht es um Geschmack und Intuition ...

Ich gehe folgendermaßen vor:

  • uRL-Pfadelement: Die Ressource und ihr Pfadelement bilden eine Verzeichnisdurchquerung und eine Unterressource (z. B./items/{id},/users/items). Wenn Sie sich nicht sicher sind, fragen Sie Ihre Kollegen, ob sie denken, dass das Durchlaufen und sie denken, dass in "einem anderen Verzeichnis" höchstwahrscheinlich das Pfadelement die richtige Wahl ist
  • uRL-Parameter: Wenn es wirklich keine Durchquerung gibt (Suchressourcen mit mehreren Abfrageparametern sind ein sehr gutes Beispiel dafür)
21
manuel aldana

IMO sollten die Parameter besser als Abfrageargumente sein. Die URL wird verwendet, um die Ressource zu identifizieren, während die hinzugefügten Abfrageparameter angeben, welchen Teil der Ressource Sie möchten, welchen Status die Ressource haben soll usw.

18
PeterWong

Gemäß der Implementierung von REST

1) Pfadvariablen werden für die direkte Aktion auf die Ressourcen verwendet, z. B. ein Kontakt oder ein Lied, z.
GET etc/api/resource/{songid} oder
GET etc/api/resource/{contactid} gibt die entsprechenden Daten zurück.

2) Query perms/argument werden für die in-direkten Ressourcen wie Metadaten eines Songs verwendet, zB GET/api/resource/{songid}? Metadata = genres, für das die Genre-Daten zurückgegeben werden das bestimmte Lied.

17
Satish Bellapu

"Pack" und POST Ihre Daten gegen den "Kontext", den der Universumsressourcen-Locator bereitstellt, was für den Locator die Nummer 1 bedeutet.

Beachten Sie die Einschränkungen bei # 2. Ich bevorzuge POSTs gegenüber # 1.

hinweis: Einschränkungen werden für diskutiert

POST in Gibt es eine maximale Größe für POST Parameterinhalt?

GET in Gibt es ein Limit für die Länge einer GET-Anfrage? und Maximale Größe von URL-Parametern in _GET

p.s. Diese Grenzwerte basieren auf den Client-Funktionen (Browser) und dem Server (Konfiguration).

16
dgm

Nach dem RI-Standard ist der Pfad für hierarchische Parameter und die Abfrage für nicht hierarchische Parameter. Ofc. Es kann sehr subjektiv sein, was für Sie hierarchisch ist.

In Situationen, in denen mehrere URIs derselben Ressource zugewiesen sind, möchte ich die zur Identifizierung erforderlichen Parameter in den Pfad und die zur Erstellung der Darstellung erforderlichen Parameter in die Abfrage einfügen. (Für mich ist es so einfacher zu routen.)

Zum Beispiel:

  • /users/123 und /users/123?fields="name, age"
  • /users und /users?name="John"&age=30

Für die Kartenreduzierung verwende ich gerne folgende Ansätze:

  • /users?name="John"&age=30
  • /users/name:John/age:30

Es liegt also wirklich an Ihnen (und Ihrem serverseitigen Router), wie Sie Ihre URIs erstellen.

Hinweis: Nur um diese Parameter zu erwähnen, handelt es sich um Abfrageparameter. Sie definieren also eine einfache Abfragesprache. Bei komplexen Abfragen (die Operatoren wie und oder größer als usw. enthalten) empfehle ich Ihnen, eine bereits vorhandene Abfragesprache zu verwenden. Die Möglichkeiten von RI-Vorlagen sind sehr begrenzt ...

5
inf3rno

Als Programmierer am Client bevorzuge ich oft das Abfrage-Argument. Außerdem trennt es für mich den URL-Pfad von den Parametern, erhöht die Übersichtlichkeit und bietet mehr Erweiterbarkeit. Außerdem kann ich eine separate Logik zwischen dem URL/URI-Gebäude und dem Parameter-Builder verwenden.

Mir gefällt, was Manuel Aldana über die andere Option gesagt hat, wenn es sich um einen Baum handelt. Ich kann sehen, dass benutzerspezifische Teile auf diese Weise entfernt werden.

4
Joe Plante

Hier ist meine Meinung.

Abfrageparameter werden als Metadaten für eine Anforderung verwendet. Sie dienen als Filter oder Modifikator für einen vorhandenen Ressourcenaufruf.

Beispiel:

/calendar/2014-08-08/events

sollte Kalenderereignisse für diesen Tag geben.

Wenn Sie Ereignisse für eine bestimmte Kategorie wünschen

/calendar/2014-08-08/events?category=appointments

oder wenn Sie Veranstaltungen von mehr als 30 Minuten benötigen

/calendar/2014-08-08/events?duration=30

Ein Lackmustest wäre zu prüfen, ob die Anfrage noch ohne Abfrageparameter zugestellt werden kann.

4
Jay

Es gibt keine festen Regeln, aber die Faustregel aus rein konzeptioneller Sicht, die ich gerne verwende, lässt sich kurz so zusammenfassen: Ein URI-Pfad (per Definition) stellt eine Ressource dar und Abfrageparameter sind im Wesentlichen Modifikatoren für diese Ressource . Bisher hilft das wahrscheinlich nicht ... Mit einer REST -API haben Sie die wichtigsten Methoden, um mit GET, PUT und DELETE auf eine einzelne Ressource zu reagieren. Ob also etwas im Pfad oder als Parameter dargestellt werden soll, lässt sich darauf reduzieren, ob diese Methoden für die betreffende Darstellung sinnvoll sind. Würden Sie PUT vernünftigerweise etwas an diesem Pfad finden, und wäre es semantisch sinnvoll, dies zu tun? Sie könnten natürlich PUT so ziemlich überall und das Back-End verbiegen, um damit umzugehen, aber Sie sollten PUT angeben, was einer Darstellung der tatsächlichen Ressource gleichkommt und nicht einer unnötig kontextualisierten Version davon. Für Sammlungen kann dasselbe mit POST gemacht werden. Wenn Sie einer bestimmten Sammlung eine URL hinzufügen möchten, die für POST zu sinnvoll ist.

Dies lässt immer noch einige Grauzonen, da einige Pfade darauf hindeuten könnten, wie viel Kinder von übergeordneten Ressourcen erhalten, was in gewisser Weise nach Belieben und abhängig von ihrer Verwendung ist. Die einzige harte Linie, die hierdurch gezogen wird, ist, dass jede Art von transitiver Repräsentation unter Verwendung eines Abfrageparameters erfolgen sollte, da dieser keine zugrunde liegende Ressource aufweisen würde.

In Anlehnung an das Beispiel aus der realen Welt in der ursprünglichen Frage (Twitter-API) stellen die Parameter eine transitiven Abfrage dar, die nach dem Status der Ressourcen (und nicht nach einer Hierarchie) filtert. In diesem speziellen Beispiel wäre es völlig unvernünftig, der Sammlung, die durch diese Einschränkungen dargestellt wird, etwas hinzuzufügen, und außerdem wäre diese Abfrage nicht in der Lage, als Pfad dargestellt zu werden, der im Sinne eines Objektgraphen keinen Sinn ergibt.

Die Übernahme dieser Art von ressourcenorientierter Perspektive kann leicht direkt auf das Objektdiagramm Ihres Domain-Modells abgebildet werden und die Logik Ihrer API dahin lenken, dass alles sehr sauber und auf eine ziemlich selbstdokumentierende Weise funktioniert, sobald es klar erkennbar ist. Das Konzept kann auch klarer werden, indem Systeme verlassen werden, die traditionelles URL-Routing verwenden, das auf ein normalerweise schlecht angepasstes Datenmodell (d. H. Ein RDBMS) abgebildet ist. Apache Sling wäre sicherlich ein guter Anfang. Das Konzept der Objektdurchquerung in einem System wie Zope liefert auch ein klareres Analogon.

4
Matt Whipple

Eine "Dimension" dieses Themas wurde ausgelassen, aber es ist sehr wichtig: Es gibt Zeiten, in denen die "Best Practices" mit der Plattform in Einklang gebracht werden müssen, die wir implementieren oder mit REST - Funktionen erweitern.

Praktisches Beispiel:

Viele Webanwendungen implementieren heutzutage die MVC-Architektur (Model, View, Controller). Sie gehen davon aus, dass ein bestimmter Standardpfad bereitgestellt wird. Dies gilt umso mehr, wenn diese Webanwendungen mit der Option "SEO-URLs aktivieren" ausgestattet sind.

Nur um eine ziemlich berühmte Webanwendung zu erwähnen: einen OpenCart E-Commerce-Shop. Wenn der Administrator die "SEO-URLs" aktiviert, erwartet er, dass diese URLs in einem ganz normalen MVC-Format vorliegen:

http://www.domain.tld/special-offers/list-all?limit=25

Wo

  • special-offers ist der MVC-Controller, der die URL verarbeiten soll (Anzeige der Seite mit Sonderangeboten)

  • list-all ist der Aktions- oder Funktionsname des Controllers, der aufgerufen werden soll. (*)

  • limit = 25 ist eine Option, die besagt, dass 25 Artikel pro Seite angezeigt werden.

(*) list-all ist ein fiktiver Funktionsname, den ich aus Gründen der Übersichtlichkeit verwendet habe. In Wirklichkeit haben OpenCart und die meisten MVC-Frameworks eine implizite (und normalerweise in der URL nicht enthaltene) index -Funktion, die aufgerufen wird, wenn der Benutzer eine Standardaktion ausführen möchte. Die URL der realen Welt wäre also:

http://www.domain.tld/special-offers?limit=25

Mit einer jetzt ziemlich standardmäßigen Anwendung oder Framework-Struktur, die der obigen ähnelt, erhalten Sie häufig einen für sie optimierten Webserver, der URLs für sie umschreibt (die wahre "nicht SEOed URL" wäre: http://www.domain.tld/index.php?route=special-offers/list-all&limit=25). .

Daher müssen Sie als Entwickler mit der vorhandenen Infrastruktur fertig werden und Ihre "Best Practices" anpassen, es sei denn, Sie sind der Systemadministrator, und wissen genau, wie Sie eine Apache/NGinx-Umschreibekonfiguration anpassen können (letztere kann böse sein!) auf.

Daher ist Ihre REST -API häufig besser, wenn Sie die Standards der verweisenden Webanwendung befolgen. Dies gilt sowohl für die Konsistenz als auch für die Benutzerfreundlichkeit/Geschwindigkeit (und damit für die Budgeteinsparung).

Um zum obigen praktischen Beispiel zurückzukehren, wäre eine konsistente REST -API etwas mit URLs wie:

http://www.domain.tld/api/special-offers-list?from=15&limit=25

oder (nicht SEO URLs)

http://www.domain.tld/index.php?route=api/special-offers-list?from=15&limit=25

mit einer Mischung aus "Pfaden gebildet" Argumenten und "Abfrage gebildet" Argumenten.

2
Dario Fumagalli

Ich tendiere im Allgemeinen zu # 2, als ein Abfrageargument (d. H./Api/resource? Parameter = value).

Eine dritte Möglichkeit besteht darin, den Parameter = value tatsächlich in den Body zu schreiben.

Dies liegt daran, dass es für Ressourcen mit mehreren Parametern besser funktioniert und für die zukünftige Verwendung erweiterbar ist.

Egal welche Sie auswählen, stellen Sie sicher, dass Sie nur eine auswählen, nicht mischen und anpassen. Das führt zu einer verwirrenden API.

2
NorthIsUp

Ich sehe viele REST APIs, die mit Parametern nicht gut umgehen. Ein häufig vorkommendes Beispiel ist, wenn der URI personenbezogene Daten enthält.

http://software.danielwatrous.com/design-principles-for-rest-apis/

Ich denke, eine logische Folgefrage ist, wann ein Parameter überhaupt kein Parameter sein sollte, sondern in den _ Header _ verschoben werden sollte oder BODY der Anfrage.

1
Daniel Watrous

Das ist eine sehr interessante Frage.

Sie können beide verwenden, es gibt keine strengen Regeln zu diesem Thema, aber die Verwendung von URI-Pfadvariablen hat einige Vorteile:

  • Cache: Die meisten Web-Cache-Dienste im Internet speichern keine GET-Anforderungen im Cache, wenn sie Abfrageparameter enthalten. Sie tun dies, weil es viele RPC-Systeme gibt, die GET-Anforderungen verwenden, um Daten auf dem Server zu ändern (fehlgeschlagen !! Get muss eine sichere Methode sein).

Wenn Sie jedoch Pfadvariablen verwenden, können alle diese Dienste Ihre GET-Anforderungen zwischenspeichern.

  • Hierarchie: Die Pfadvariablen können eine Hierarchie darstellen:/Stadt/Straße/Ort

Es gibt dem Benutzer mehr Informationen über die Struktur der Daten.

Wenn Ihre Daten jedoch keine Hierarchiebeziehung haben, können Sie weiterhin Pfadvariablen mit Komma oder Semikolon verwenden:

/ Stadt/Länge, Breite

Verwenden Sie in der Regel ein Komma, wenn die Reihenfolge der Parameter von Bedeutung ist, und ein Semikolon, wenn die Reihenfolge keine Rolle spielt:

/ IconGenerator/rot; blau; grün

Abgesehen von diesen Gründen kommt es in einigen Fällen häufig vor, dass Abfragezeichenfolgenvariablen verwendet werden:

  • Wenn der Browser HTML-Formularvariablen automatisch in den URI einfügen soll
  • Wenn es um Algorithmen geht. Beispielsweise verwendet die Google-Engine Abfragezeichenfolgen:

http: // www.google.com/search?q=rest

Zusammenfassend lässt sich sagen, dass es keinen guten Grund gibt, eine dieser Methoden zu verwenden. Verwenden Sie jedoch URI-Variablen, wann immer Sie können.

0
jfcorugedo