REST-URI-Konvention - Singular- oder Pluralname der Ressource beim Erstellen

529

Ich bin neu in REST und habe festgestellt, dass in einigen RESTful-Diensten unterschiedliche Ressourcen-URIs zum Aktualisieren / Abrufen / Löschen und Erstellen verwendet werden. Sowie

  • Erstellen - Verwenden von / resources mit der POST-Methode (Plural beobachten) an einigen Stellen mit / resource (Singular)
  • Update - mit / resource / 123 mit PUT-Methode
  • Get - Using / resource / 123 mit der GET-Methode

Ich bin ein bisschen verwirrt über diese URI-Namenskonvention. Was sollten wir Plural oder Singular für die Ressourcenerstellung verwenden? Was sollten die Kriterien sein, um das zu entscheiden?

JPReddy
quelle
9
Im Anschluss an dieses Thema habe ich in einem Artikel einige Beispiele berühmter REST-APIs zusammengefasst: inmensosofa.blogspot.com/2011/10/… .
Jjmontes
3
Die Schlussfolgerung, zu der ich nach dem Lesen aller folgenden Antworten gelangt bin: Verwenden Sie immer Singular, weil (a) es konsistent ist, (b) es direkt Singularklassen- und Tabellennamen zugeordnet ist, (c) einige Pluralnomen im Englischen unregelmäßig (unvorhersehbar) sind
Will Sheppard
In dieser Antwort finden Sie einen Link zu den Namenskonventionen für einzelne Tabellen. In einem weiteren Artikel wird genau dieses Problem erwähnt. Das Dilemma des Rest API-Entwicklers - danke @Sorter
Will Sheppard,

Antworten:

281

Die Voraussetzung für die Verwendung /resourcesist, dass sie "alle" Ressourcen darstellt. Wenn Sie a ausführen GET /resources, werden Sie wahrscheinlich die gesamte Sammlung zurückgeben. Durch POSTEN an fügen /resourcesSie der Sammlung etwas hinzu.

Die einzelnen Ressourcen sind jedoch unter / resource verfügbar. Wenn Sie a ausführen GET /resource, werden Sie wahrscheinlich einen Fehler machen, da diese Anfrage keinen Sinn ergibt, während dies /resource/123durchaus Sinn macht.

Unter Verwendung /resourceanstelle von /resourcesähnelt , wie Sie dies tun würden , wenn Sie mit, sagen wir gearbeitet haben, ein Dateisystem und eine Sammlung von Dateien und /resourceist das „Verzeichnis“ mit den einzelnen 123, 456Dateien darin.

Keiner der Wege ist richtig oder falsch, gehen Sie mit dem, was Ihnen am besten gefällt.

Will Hartung
quelle
55
Gute Antwort! "Standard" -Verzeichnisse in Windows haben jedoch mehrere Namen. Wie "Programme", "Benutzer", "Dokumente", "Videos" usw. Auch bin ich viel häufiger auf mehrere Namen in Website-URLs gestoßen.
Dmitry Gonchar
50
Die Defacto-Konvention, die die meisten Leute und APIs da draußen anwenden, ist, dass sie jederzeit im Plural bleibt. IDs geben EINE Ressource Autos / ID
PositiveGuy
205
"Keiner der Wege ist richtig oder falsch, gehen Sie mit dem, was Ihnen am besten gefällt." Ah, die berühmte Linie, die ich so oft höre und die es satt habe, von Menschen zu hören. Konventionen sind wichtig und sollten in der Community konstruktiv diskutiert werden. Hier entstehen bessere Lösungen und bewährte Verfahren. Wenn Sie sowohl Plural als auch Singular für Ressourcennamen in URIs verwenden, verkompliziert dies Ihren Code und die API, da der Benutzer und der Code hinter der API dies in Routen und Logik berücksichtigen müssen, um zwischen Single und Plural zu unterscheiden, während Sie nur bleiben Mit Plural haben Sie die ganze Zeit keine Probleme.
PositiveGuy
30
@TomaszPluskiewicz Sie haben völlig Recht, dass Kunden sich nicht darum kümmern. Als Softwareentwickler sollten wir uns darum kümmern - und dafür stimme ich der Bemerkung von WTF zu, dass konstruktive Debatten über Konventionen wertvoll sind.
Travis D
12
Kann also jemand einfach eine Antwort mit einem Wort geben und akzeptieren lassen, damit ich das alles nicht (noch einmal) lesen muss?
Ben George
623

Für mich ist es besser, ein Schema zu haben, das Sie direkt dem Code zuordnen können (einfach zu automatisieren), hauptsächlich weil Code an beiden Enden vorhanden sein wird.

GET  /orders          <---> orders 
POST /orders          <---> orders.push(data)
GET  /orders/1        <---> orders[1]
PUT  /orders/1        <---> orders[1] = data
GET  /orders/1/lines  <---> orders[1].lines
POST /orders/1/lines  <---> orders[1].lines.push(data) 
jla
quelle
22
Die Schwierigkeit oder Leichtigkeit davon ist darauf zurückzuführen, dass HATEOS nicht respektiert wird. Es sollte keine Rolle spielen, ob es Plural oder Singular ist oder irgendetwas anderes. Sie sollten die vom Server gesendeten Uris respektieren und Ihre Uris nicht auf dem Client "aufbauen". Dann müssen Sie 0 Mapping für Ihren Code durchführen.
Richard
7
@richard Der Client muss noch ein Mapping durchführen. In HATEOS müssten sie einem Namen zugeordnet werden, der die Beziehung (rel) zur URI-Konstruktion darstellt. Rel, Methode (Verb) und Inhaltstyp bilden dann das Ressourcenmedium. Dies schließt die Notwendigkeit eines guten URI-Designs nicht aus. Auch wenn der Client dem rel-Namen Vorrang einräumt, benötigen die Entwickler der API dennoch einen guten, für Menschen lesbaren Standard für die URI-Erstellung.
4
Dies ist meiner Meinung nach eine bessere Antwort. Abgesehen davon, dass ich es immer vorgezogen habe, Singular anstelle von Plural zu verwenden. User.getList (), User.getById, User.delete usw.
Eastern Monk
3
Ich mag die Einfachheit. Das Mapping hat auch den Vorteil, dass Dokumentation und Tests auf Routen unglaublich einfach zu schreiben sind.
Delos
5
Das macht für mich Sinn. Wir sind jedoch ein Datenbank-First-Shop, dh wir generieren Code- und API-Entitäten aus unserem Datenbankschema. Und Datenbankstandards tendieren dazu, singuläre Tabellennamen zu befürworten, also gehen wir damit um, aber immer noch unter der gleichen Logik wie diese Antwort.
André C. Andersen
274

Ich sehe auch keinen Sinn darin und ich denke, es ist nicht das beste URI-Design. Als Benutzer eines RESTful-Dienstes würde ich erwarten, dass die Listenressource denselben Namen hat, unabhängig davon, ob ich auf die Liste oder auf eine bestimmte Ressource in der Liste zugreife. Sie sollten dieselben Bezeichner verwenden, unabhängig davon, ob Sie die Listenressource oder eine bestimmte Ressource verwenden möchten.

Jan Deinhard
quelle
69
Dies ist für mich die beste Antwort. Ich schätze, dass API-Designer die sprachliche Korrektheit der Angabe "get resource # 123" mögen, aber es ist ein zusätzlicher Codierungsaufwand beim Schreiben von Clients der API sowie bei der Hilfedokumentation. (GET / api / people vs. GET / api / person / 123? Euuuchh.) .... anstatt es als "get resource # 123" zu betrachten, formulieren Sie es in Ihrem Kopf wie "get from the collection of resources that" entspricht # 123 ".
Warren Rumak
5
Bei der Unterscheidung von Plural- / Singularressourcen geht es nicht um sprachliche Korrektheit, sondern um Skalierung. / employee / 12 liest mir als Teilmenge der Mitarbeiterressource mit der ID '12' vor (dies kann alles bedeuten, z. B. eine gespeicherte Suchabfrage für kürzlich entlassene Mitarbeiter). Wenn Sie das oben Gesagte als Mitarbeiter mit der ID '12' lesen, wie würden Sie die Teilmenge darstellen? Die einzige Möglichkeit besteht darin, das komplexere Erz von URIs Sammlungen, die Objekte enthalten, von den Objekten selbst zu unterscheiden (dh Singular gegen Plural).
Erik
9
Die Auswahl von / employee / 12 zur Darstellung einer Suchabfrage für kürzlich entlassene Mitarbeiter (oder eine beliebige Teilmenge) wäre meines Erachtens ein schlechtes Design. Wenn Sie Teilmengen jeglicher Art darstellen möchten, schlage ich vor, sie als eigenständige Ressourcen (mit Eigennamen) einzuführen.
Jan Deinhard
3
Dies hat nichts mit der Verständlichkeit für die Kunden zu tun. Es geht darum, verschiedene Dinge mit verschiedenen URLs anzusprechen. Und in der Lage zu sein, auf alle HTTP-Methoden zu reagieren, ohne in Konflikt zu geraten. Sie können eine Ressource haben, die eine Sammlung von Elementen ist, und eine Ressource, die ein Element selbst darstellt. Soweit es mich interessiert, könnte die Sammlungsressource example.org/166316e2-e1 und ein bestimmtes Element in dieser Sammlung example.org/20d68348-ccc-001c4200de sein . Der Client sollte keine URLs erstellen (das ist offensichtlich nicht skalierbar, es ist nicht RESTful und dafür sind Linkbeziehungstypen gedacht).
Erik
4
Wenn Sie nicht der Meinung sind, dass beliebige URLs hübsch sind, können Sie eine Sammlungsressource mit einem Pluralnamen und ein einzelnes Element mit einem Singularnamen identifizieren. Wenn Sie keine englischen URLs mögen und Ihre natürliche Sprache diese Art der Singular- / Plural-Notation nicht unterstützt, verwenden Sie etwas anderes, um sie in Ihrer bevorzugten Sprache zu definieren. Ich nehme an, alle Sprachen ermöglichen es Ihnen, '/ the-collection-of- bla / 2321 'versus' bla / 61 'schriftlich. Und jede dieser beiden unterschiedlichen Ressourcen stellt beim Senden von GET / PUT / DELETE / POST / PATCH und anderen völlig unterschiedliche Ergebnisse dar.
Erik
77

Plural

  • Einfach - alle URLs beginnen mit demselben Präfix
  • Logisch - orders/Ruft eine Indexliste der Bestellungen ab.
  • Standard - Am weitesten verbreiteter Standard, gefolgt von der überwiegenden Mehrheit der öffentlichen und privaten APIs.

Zum Beispiel:

GET /resources - gibt eine Liste der Ressourcenelemente zurück

POST /resources - Erstellt ein oder mehrere Ressourcenelemente

PUT /resources - Aktualisiert ein oder mehrere Ressourcenelemente

PATCH /resources - aktualisiert teilweise ein oder mehrere Ressourcenelemente

DELETE /resources - löscht alle Ressourcenelemente

Und für einzelne Ressourcenelemente:

GET /resources/:id- gibt ein bestimmtes Ressourcenelement basierend auf dem :idParameter zurück

POST /resources/:id - erstellt ein Ressourcenelement mit der angegebenen ID (erfordert eine Validierung)

PUT /resources/:id - Aktualisiert ein bestimmtes Ressourcenelement

PATCH /resources/:id - aktualisiert teilweise ein bestimmtes Ressourcenelement

DELETE /resources/:id - löscht ein bestimmtes Ressourcenelement

Stellen Sie sich die Befürworter von Singular folgendermaßen vor: Würden Sie jemanden nach einem fragen orderund eine Sache oder eine Liste von Dingen erwarten? Warum sollten Sie also erwarten, dass ein Dienst beim Tippen eine Liste von Dingen zurückgibt /order?

Eric Knudtson
quelle
10
Singular : Falls ein Teil Ihres Systems nur ein Objekt ist (0-1, existiert oder nicht), z. B. Benutzer / 1 / Avatar, können Sie dieses einzelne Objekt (z. B. Avatar) in Singularform kennzeichnen - detaillierteres Beispiel hier: Stackoverflow .com / a / 38296217/860099 . Übrigens - sehr schöne Antwort :)
Kamil Kiełczewski
Was ist mit der Zuordnung zu Klassen- und Tabellennamen, die singulär sein sollten? (siehe andere Antwort )
Will Sheppard
@WillSheppard - Klassennamen sind am besten in Singularform und Tabellennamen sind am besten in Pluralform. Zum Beispiel Orderist ein guter Name für eine Klasse, die sich mit einzelnen Instanzen von Objekten befasst, die sich auf eine Reihenfolge beziehen. OrderListist ein Name für eine Klasse, die sich mit mehreren OrderInstanzen befasst. Orders Tableist ein guter Name für eine Datenbanktabelle mit vielen Aufträgen.
Eric Knudtson
Ich möchte / Bestellungen bekommen, aber ich möchte nur / 1
Jim Smith
@ Jim-Smith, warum fordern Sie dann nicht / 1 aus der Sammlung von Benutzern mit GET / users / 1 an?
Rohmer
49

Singular

Bequemlichkeit Dinge können unregelmäßige Pluralnamen haben. Manchmal haben sie keine. Aber Singularnamen sind immer da.

zB CustomerAddress über CustomerAddresses

Betrachten Sie diese verwandte Ressource.

Dies /order/12/orderdetail/12ist lesbarer und logischer als /orders/12/orderdetails/4.

Datenbanktabellen

Eine Ressource repräsentiert eine Entität wie eine Datenbanktabelle. Es sollte einen logischen Singularnamen haben. Hier ist die Antwort über Tabellennamen.

Klassenzuordnung

Klassen sind immer einzigartig. ORM-Tools generieren Tabellen mit denselben Namen wie Klassennamen. Da immer mehr Werkzeuge verwendet werden, werden einzelne Namen zum Standard.

Lesen Sie mehr über das Dilemma eines REST-API-Entwicklers

Sorter
quelle
39
Singuläre Namen sind immer da /clothe/12/trouser/34 :)
Gert Arnold
18
@GertArnold das Wort clotheist ein Verb. Rest-APIs halten sich im Allgemeinen an Substantive, wenn sie über Ressourcen sprechen, und verwenden Verben, wenn sie Aktionen beschreiben. Die Singularform ist clout, ist aber archaisch und würde wahrscheinlich geeigneter durch ersetzt werden garment.
Steve Buzonas
@SteveBuzonas Und für Hosen und Sonnenbrillen?
Koray Tugay
32

Während die am weitesten verbreitete Praxis RESTful Apis sind, bei denen Pluralformen verwendet werden, z /api/resources/123 gibt es einen Sonderfall, in dem ich die Verwendung eines Singularnamens angemessener / ausdrucksvoller finde als Pluralnamen. Es ist der Fall von Eins-zu-Eins-Beziehungen. Insbesondere, wenn das Zielelement ein Wertobjekt ist (im domänengesteuerten Entwurfsparadigma).

Nehmen wir an, jede Ressource hat eine Eins-zu-Eins-Ressource, accessLogdie als Wertobjekt modelliert werden kann, dh keine Entität, daher keine ID. Es könnte ausgedrückt werden als /api/resources/123/accessLog. Die üblichen Verben (POST, PUT, DELETE, GET) würden die Absicht und auch die Tatsache, dass die Beziehung tatsächlich eins zu eins ist, angemessen ausdrücken.

redzedi
quelle
4
Netter Versuch. Aber es wäre besser als "accessLogEntries". :-)
Tom Russell
8
@ TomRussell warum? Die Auswirkungen sind wichtig. Ich verstehe, warum Sie Plural verwenden würden, selbst wenn Sie über eine Kennung auf eine Ressource zugreifen, aber für viele zu eins oder eins zu eins ist es ziemlich irreführend. Stellen Sie sich eine API vor, die Mitarbeiter eines Unternehmens mit mehreren Standorten verwaltet. Jeder Mitarbeiter arbeitet an einem Ort. GET /users/123/locationsollte den Ort abrufen, an dem der Benutzer arbeitet. Ist es GET /users/123/locationsals Verbraucher nicht wirklich irreführend?
Carrie Kendall
1
@ CarrieKendall Ich verstehe deinen Standpunkt. Da accessLoges als Attribut oder Wert und nicht als Entität modelliert wird, sollte es singulär sein. Wenn Sie zu viel Engineering benötigen, ist ein Protokolleintrag eine Entität, die Sie haben würden /api/accessLogEntries?resource=123.
Tom Russell
Einverstanden, obwohl ich denke, dass es gegen die Konvention verstößt, alle Dinge zu pluralisieren. Es ist eine schwierige Frage. Für mich ist es wichtig, dass eine API unkompliziert ist, dh die Dokumentation sollte eine bereits unkomplizierte Implementierung ergänzen.
Carrie Kendall
Ich bin eher ein Programmierer als eine System- oder Datenbankperson, daher mag ich eine API, die eine Geschichte erzählt, anstatt sich an Konventionen zu halten. Die Auswirkungen auf die automatisierte Dokumentation sind jedoch real.
Tom Russell
26

Warum nicht dem vorherrschenden Trend der Namen von Datenbanktabellen folgen, bei denen eine singuläre Form allgemein akzeptiert wird? War schon da, hab das gemacht - lass uns wiederverwenden.

Tabellennamensdilemma: Singular vs. Plural Names

Slawomir
quelle
8
Das Auto ist viel besser als Die Autos. Auch sind englische Plural-Konventionen nicht konsistent.
FlavorScape
7
Der Ressourcennamensraum ist eine Frage der Semantik, nicht der Implementierung. Die Verwendung der DB-Tabellen-Analogie ist also nicht sehr glücklich. Auch wenn Sie mit DBs arbeiten, bearbeiten Sie nur Tabellen, obwohl Sie natürlich den Inhalt (Zeilen) beeinflussen können, aber in REST gibt es keine Einschränkung, eine einzelne Ressource direkt zu bearbeiten .
Arpadf
3
Ich denke, dies ist eine gute Analogie, aber wichtiger als die Entscheidung, ob Singular oder Plural gewählt werden soll, ist die Übereinstimmung mit der von Ihnen gewählten Wahl. Sie werden nicht in Benutzer einfügen und dann unter Benutzer auswählen. Die gleiche Regel sollte für REST-Ressourcen gelten. Benennen Sie sie nicht um, je nachdem, was Sie tun.
Todd Menier
3
Es sind nicht nur Tabellennamen, sondern auch vergleichbar mit Klassennamen in OO (meine Klasse würde Kunde und nicht Kunden heißen).
Bytedev
In diesem Fall ist die Semantik zu wichtig, um einfach "bereits definierte" Trends zu akzeptieren
Cattani Simone
19

Ich bin überrascht zu sehen, dass so viele Menschen auf den Plural Nomen Bandwagon springen würden. Kümmern Sie sich bei der Implementierung von Konvertierungen von Singular in Plural um unregelmäßige Substantive im Plural? Magst du Schmerzen?

Siehe http://web2.uvcs.uvic.ca/elc/studyzone/330/grammar/irrplu.htm

Es gibt viele Arten von unregelmäßigem Plural, aber diese sind die häufigsten:

Nomen-Typ Bildung des Plural-Beispiels

Ends with -fe   Change f to v then Add -s   
    knife   knives 
    life   lives 
    wife   wives
Ends with -f    Change f to v then Add -es  
    half   halves 
    wolf   wolves
    loaf   loaves
Ends with -o    Add -es 
    potato   potatoes
    tomato   tomatoes
    volcano   volcanoes
Ends with -us   Change -us to -i    
    cactus   cacti
    nucleus   nuclei
    focus   foci
Ends with -is   Change -is to -es   
    analysis   analyses
    crisis   crises
    thesis   theses
Ends with -on   Change -on to -a    
    phenomenon   phenomena
    criterion   criteria
ALL KINDS   Change the vowel or Change the word or Add a different ending   
     man   men
     foot   feet
     child   children
     person   people
     tooth   teeth
     mouse   mice
 Unchanging Singular and plural are the same    
     sheep deer fish (sometimes)
Stephan Erickson
quelle
5
Ich verstehe die Besorgnis hier nicht. Wir sollen Singular nicht programmatisch in Plural ändern. Die meisten der oben genannten Pluralformen sind bekannt und sollten kein Problem darstellen. Wenn jemand schlechte Englischkenntnisse hat, wird er einen Teil Ihrer Variablen falsch buchstabieren. Empfehlen Sie nach Ihrer Logik auch die Verwendung einzelner Formulare, um Sammlungen im Quellcode zu referenzieren?
Kishor Borate
1
Es gibt englische Wörter, die so unregelmäßig sind, dass sie selbst innerhalb der Anglosphäre häufig ein Problem darstellen, und sie werden häufig als Begriffe / Index / Indizes / Indizes, Vertix / Vertixe / Vertices, Matrix / Matrizen / Matrizen, Radius / Radius / verwendet. Radien usw. Ich sehe keinen Sinn darin, REST-Pfade ohnehin plural zu machen, denn wenn sie alle durchgehend singulär sind, ist dies für alle nur offensichtlicher.
Verdammter
@kishorborate, Die Verwendung von Plural als URI ist selbst für englische Muttersprachler fehleranfälliger. Wie verdammt zeigt, bringen Pluralformen wie Index / Indizes / Indizes mehr Probleme mit sich. Und es gibt unzählige Substantive. Ein weiteres Problem ist das Mischen unzähliger Substantive mit Pluralformen. Warum ist es für Programmierer schwieriger, mehr Zeit damit zu verbringen? Ich schlage vor, Singulars für alles zu verwenden. Wenn eine / {id} vorhanden ist, sollte die API einen einzelnen Datensatz zurückgeben. Wenn keine / {id} folgt, sollte die API die Auflistung zurückgeben.
Daming Fu
3
@DamingFu Singular-Ressource ist möglicherweise nicht immer eine ID zugeordnet. z.B. / user / {id} / nickName Wenn man es sich ansieht, ist nicht klar, ob es eine Liste von nickNames oder einen einzelnen nickName zurückgibt? Daher sind APIs intuitiver, wenn mehrere Formen verwendet werden. Ja, wenige Wörter haben unregelmäßige Pluralformen. Für jemanden, der die Pluralform liest, ist das kein Problem. Dies tritt nur beim Schreiben der API-Signatur auf. Die Häufigkeit solcher Wörter ist jedoch nicht hoch, und das Finden der Pluralform eines Wortes ist nicht zeitaufwändig. Es ist ein Kompromiss, den wir akzeptieren sollten, um APIs intuitiver zu gestalten.
Kishor Borate
15

Aus Sicht des API-Verbrauchers sollten die Endpunkte vorhersehbar sein

Im Idealfall...

  1. GET /resources sollte eine Liste von Ressourcen zurückgeben.
  2. GET /resource sollte einen Statuscode mit 400 Ebenen zurückgeben.
  3. GET /resources/id/{resourceId} sollte eine Sammlung mit einer Ressource zurückgeben.
  4. GET /resource/id/{resourceId} sollte ein Ressourcenobjekt zurückgeben.
  5. POST /resources sollte Stapel Ressourcen erstellen.
  6. POST /resource sollte eine Ressource erstellen.
  7. PUT /resource sollte ein Ressourcenobjekt aktualisieren.
  8. PATCH /resource sollte eine Ressource aktualisieren, indem nur die geänderten Attribute veröffentlicht werden.
  9. PATCH /resources sollten Batch-Aktualisierungsressourcen nur die geänderten Attribute veröffentlichen.
  10. DELETE /resourcessollte alle Ressourcen löschen; nur ein Scherz: 400 Statuscode
  11. DELETE /resource/id/{resourceId}

Dieser Ansatz ist am flexibelsten und funktionsreichsten, aber auch am zeitaufwändigsten zu entwickeln. Wenn Sie es also eilig haben (was bei der Softwareentwicklung immer der Fall ist), nennen Sie einfach Ihren Endpunkt resourceoder die Pluralform resources. Ich bevorzuge die Singularform, weil Sie die Möglichkeit haben, programmgesteuert nach innen zu schauen und zu bewerten, da nicht alle Pluralformen mit 's' enden.

Abgesehen davon, aus welchem ​​Grund auch immer, haben sich die am häufigsten verwendeten Praxisentwickler für die Verwendung der Pluralform entschieden. Dies ist letztendlich die Route, die ich gewählt habe und wenn man sich beliebte Apis wie githubund ansiehttwitter , ist dies das, was sie tun.

Einige Kriterien für die Entscheidung könnten sein:

  1. Was sind meine zeitlichen Einschränkungen?
  2. Welche Operationen erlaube ich meinen Verbrauchern?
  3. Wie sieht die Nutzlast für Anforderung und Ergebnis aus?
  4. Möchte ich Reflection verwenden und den URI in meinem Code analysieren können?

Also liegt es an dir. Was auch immer Sie tun, seien Sie konsequent.

cosbor11
quelle
1
Anscheinend wurde die Pluralform gewählt, da Entwickler anscheinend davon ausgehen, dass alle Ressourcen von Natur aus Teil einer Sammlung sind. Die "akzeptierte Konvention" scheint jedoch anzugeben, dass POST /usersein einzelner Benutzer erstellt und der Sammlung hinzugefügt werden soll. Ich stimme dir nicht zu. POST /userssollte eine Liste von Benutzern erstellen (auch wenn dies eine Liste von 1 ist), wobei as POST /usergenau einen Benutzer erstellen sollte. Ich sehe keinen Grund, warum sowohl mehrere als auch einzelne Ressourcenendpunkte nicht nebeneinander existieren können. Sie beschreiben unterschiedliche Verhaltensweisen und sollten niemanden von ihrer Funktion überraschen.
Crush
Gibt es keine Konvention zum Angeben einer Ressourcen-ID im Pfad? Wenn ja, scheint es weitgehend vernachlässigt zu werden. Zum Beispiel POST users/<id>würde ein neuer Benutzer erstellen.
Tom Russell
1
@ TomRussell Normalerweise erstellt der Server die ID, sodass Sie die ID, an die POST gesendet werden soll, noch nicht kennen.
Alex
3
@TomRussell: Wenn der Client beim Erstellen einer neuen Ressource eine Art ID ermittelt, wird diese häufiger verwendet PUT /users/<id>als POST. POSThat die Interpretation "füge dies der Sammlung hinzu und bestimme die ID als Teil davon". PUThat die Interpretation "Aktualisieren (oder Hinzufügen) dieser Ressource mit dieser ID." Eine ausführlichere Erläuterung dieses Prinzips finden Sie unter restcookbook.com/HTTP%20Methods/put-vs-post .
Jochem Schulenklopper
Ich glaube nicht, dass der Vergleich mit der Twitters-API fair ist, da sie die Plural-Form für alle ihre Endpunkte verwenden. Sie mischen nicht Plural und Singular für dieselben Elemente.
Andrew T Finnell
7

Meine zwei Cent: Methoden, die ihre Zeit damit verbringen, von Plural zu Singular oder umgekehrt zu wechseln, sind eine Verschwendung von CPU-Zyklen. Ich mag altmodisch sein, aber zu meiner Zeit wurden die Dinge gleich genannt. Wie suche ich nach Methoden für Menschen? Kein regelmäßiger Ausdruck deckt sowohl Personen als auch Personen ohne unerwünschte Nebenwirkungen ab.

Englische Pluralformen können sehr willkürlich sein und belasten den Code unnötig. Halten Sie sich an eine Namenskonvention. Bei Computersprachen sollte es um mathematische Klarheit gehen, nicht um die Nachahmung natürlicher Sprache.

Guichito
quelle
2
Dies befasst sich mit Code, der versucht, Endpunkte automatisch zu generieren / zu entstellen (es gibt viele Bibliotheken mit einer Meinung, die Pluralität / Singularität annehmen und versuchen, eine Zuordnung vorzunehmen). Dies gilt jedoch nicht mehr für explizit ausgewählte Endpunktnamen als für die Auswahl des richtigen Wortes (unabhängig davon, wie es pluralisiert ist).
user2864740
6

Ich bevorzuge die Verwendung der Singularform sowohl für die Einfachheit als auch für die Konsistenz.

Zum Beispiel unter Berücksichtigung der folgenden URL:

/ Kunde / 1

Ich werde den Kunden als Kundensammlung behandeln, aber der Einfachheit halber wird der Sammlungsteil entfernt.

Ein anderes Beispiel:

/ Ausrüstung / 1

In diesem Fall haben Ausrüstungen nicht die richtige Pluralform. Wenn Sie es also als Ausrüstungssammlung behandeln und der Einfachheit halber entfernen, stimmt es mit dem Kundenfall überein.

ivxivx
quelle
2
POST / Kunde klingt so, als würde er den einzigen Kunden ersetzen. Dies ist meine größte Trauer bei der Verwendung einzelner Ressourcennamen.
Andrew T Finnell
2
@ andrew-t-finnell Soll nicht genau POST /customerdas tun - einen einzelnen Kunden einfügen?
Donmutti
Es fügt einen einzelnen Kunden in eine Sammlung von Kunden ein. POST /customerliest mir vor, als würde es an den theKunden gesendet . Keine Sammlung von Kunden. Ich gebe jedoch zu, dass Plural oder nicht Plural eine Präferenz ist. Solange sie nicht wie die andere Antwort gemischt sind. Das wäre unglaublich verwirrend.
Andrew T Finnell
"POST'ing to the customer" macht in diesem Fall keinen Sinn. POST ersetzt nicht, es fügt ein. Wenn es POST / customer / 1 wäre, könnte ich vielleicht das Dilemma sehen, aber selbst das macht aus REST-Sicht nicht viel Sinn, denn was fügen Sie ein? Es wäre / Kunde / 1 / Rechnung oder / Kunde / 1 / Quittung usw.
verdammt
5

Eine ID in einer Route sollte genauso angezeigt werden wie ein Index für eine Liste, und die Benennung sollte entsprechend erfolgen.

numbers = [1, 2, 3]

numbers            GET /numbers
numbers[1]         GET /numbers/1
numbers.push(4)    POST /numbers
numbers[1] = 23    UPDATE /numbers/1

Einige Ressourcen verwenden jedoch keine IDs in ihren Routen, da entweder nur eine vorhanden ist oder ein Benutzer nie Zugriff auf mehr als eine hat. Dies sind also keine Listen:

GET /dashboard
DELETE /session
POST /login
GET /users/{:id}/profile
UPDATE /users/{:id}/profile
TiggerToo
quelle
4

Bei Namenskonventionen ist es normalerweise sicher zu sagen, dass Sie nur eine auswählen und dabei bleiben müssen, was Sinn macht.

Nachdem Sie REST vielen Personen erklären müssen, ist die Darstellung von Endpunkten als Pfade in einem Dateisystem die ausdrucksstärkste Methode.
Es ist zustandslos (Dateien existieren oder existieren nicht), hierarchisch, einfach und vertraut - Sie wissen bereits, wie Sie lokal oder über http auf statische Dateien zugreifen können.

In diesem Zusammenhang können sprachliche Regeln Sie nur bis zu folgenden Punkten führen:

Ein Verzeichnis kann mehrere Dateien und / oder Unterverzeichnisse enthalten und daher sein Name sollte in Pluralform sein.

Und ich mag es.
Auf der anderen Seite - es ist Ihr Verzeichnis, können Sie es "eine Ressource oder mehrere Ressourcen" nennen, wenn Sie dies möchten. Das ist nicht wirklich wichtig.

Wichtig ist, dass Sie /resourceS/123nicht erwarten können, dass Sie auf eine Datei mit dem Namen "123" in einem Verzeichnis mit dem Namen "resourceS" zugreifen können (was dazu führt ) /resource/123.

Versuchen Sie nicht, es intelligenter zu machen, als es sein muss - der Wechsel von Plural zu Singluar, abhängig von der Anzahl der Ressourcen, auf die Sie gerade zugreifen, mag für manche ästhetisch ansprechend sein, aber es ist nicht effektiv und macht in a keinen Sinn hierarchisch System.

Hinweis: Technisch gesehen können Sie "symbolische Links" /resources/123erstellen , so dass auch über zugegriffen werden kann /resource/123, aber erstere müssen noch vorhanden sein!

Narf
quelle
3

Schauen Sie sich das API-Designhandbuch von Google an : Ressourcennamen für ein anderes nehmen auf die Benennung Ressourcen.

Zusamenfassend:

  • Sammlungen sind mit Pluralformen benannt.
  • Einzelne Ressourcen werden mit einer Zeichenfolge benannt.
|--------------------------+---------------+-------------------+---------------+--------------|
| API Service Name         | Collection ID | Resource ID       | Collection ID | Resource ID  |
|--------------------------+---------------+-------------------+---------------+--------------|
| //mail.googleapis.com    | /users        | /[email protected] | /settings     | /customFrom  |
| //storage.googleapis.com | /buckets      | /bucket-id        | /objects      | /object-id   |
|--------------------------+---------------+-------------------+---------------+--------------|

Es lohnt sich zu lesen, wenn Sie über dieses Thema nachdenken.

Shannon Matthews
quelle
2

Die Verwendung von Plural für alle Methoden ist zumindest in einem Aspekt praktischer: Wenn Sie eine Ressourcen-API mit Postman (oder einem ähnlichen Tool) entwickeln und testen, müssen Sie den URI nicht bearbeiten, wenn Sie von GET zu PUT zu POST usw. Wechseln .

Paulo Merson
quelle
1
Für mich ist dies kein Argument, da Postman Sammlungen anbietet. Sie können also alle Ressourcen als verschiedene Sammlungselemente speichern und einzeln testen. Alles, was Sie tun, ist die Auswahl einer Ressource aus der Sammlung. Sie müssen nicht jedes Mal Parameter / Methoden / usw. bearbeiten.
Wirone
1

Beide Darstellungen sind nützlich. Ich hatte Singular aus Bequemlichkeitsgründen für einige Zeit verwendet, Beugung kann schwierig sein. Aufgrund meiner Erfahrung bei der Entwicklung streng singulärer REST-APIs fehlt den Entwicklern, die den Endpunkt verwenden, die Gewissheit über die Form des Ergebnisses. Ich bevorzuge es jetzt, den Begriff zu verwenden, der die Form der Antwort am besten beschreibt.

Wenn alle Ihre Ressourcen auf höchstem Niveau sind, können Sie mit einzelnen Darstellungen davonkommen. Beugung zu vermeiden ist ein großer Gewinn.

Wenn Sie eine Art Deep Linking durchführen, um Abfragen zu Beziehungen darzustellen, können Entwickler, die gegen Ihre API schreiben, durch eine strengere Konvention unterstützt werden.

Meine Konvention ist, dass jede Tiefenebene in einem URI eine Interaktion mit der übergeordneten Ressource beschreibt und der vollständige URI implizit beschreiben sollte, was abgerufen wird.

Angenommen, wir haben das folgende Modell.

interface User {
    <string>id;
    <Friend[]>friends;
    <Manager>user;
}

interface Friend {
    <string>id;
    <User>user;
    ...<<friendship specific props>>
}

Wenn ich eine Ressource bereitstellen müsste, mit der ein Client den Manager eines bestimmten Freundes eines bestimmten Benutzers abrufen kann, könnte dies folgendermaßen aussehen:

GET /users/{id}/friends/{friendId}/manager

Im Folgenden sind einige weitere Beispiele aufgeführt:

  • GET /users - Listen Sie die Benutzerressourcen in der globalen Benutzersammlung auf
  • POST /users - Erstellen Sie einen neuen Benutzer in der globalen Benutzersammlung
  • GET /users/{id} - einen bestimmten Benutzer aus der globalen Benutzersammlung abrufen
  • GET /users/{id}/manager - Holen Sie sich den Manager eines bestimmten Benutzers
  • GET /users/{id}/friends - Holen Sie sich die Liste der Freunde eines Benutzers
  • GET /users/{id}/friends/{friendId} - einen bestimmten Freund eines Benutzers finden
  • LINK /users/{id}/friends - Fügen Sie diesem Benutzer eine Freundesvereinigung hinzu
  • UNLINK /users/{id}/friends - Entfernen Sie eine Freundesvereinigung von diesem Benutzer

Beachten Sie, wie jede Ebene einem übergeordneten Element zugeordnet wird, auf das reagiert werden kann. Die Verwendung verschiedener Eltern für dasselbe Objekt ist nicht intuitiv. Das Abrufen einer Ressource unter GET /resource/123lässt keinen Hinweis darauf, dass das Erstellen einer neuen Ressource unter erfolgen sollPOST /resources

Steve Buzonas
quelle
1

Ich weiß, dass die meisten Menschen zwischen der Entscheidung, ob sie Plural oder Singular verwenden, stehen. Das Problem, das hier nicht angesprochen wurde, ist, dass der Client wissen muss, welches Sie verwenden, und dass er immer wahrscheinlich einen Fehler macht. Hier kommt mein Vorschlag her.

Wie wäre es mit beidem? Und damit meine ich, verwenden Sie Singular für Ihre gesamte API und erstellen Sie dann Routen, um Anforderungen im Plural an die Singularform weiterzuleiten. Zum Beispiel:

GET  /resources     =     GET  /resource
GET  /resources/1   =     GET  /resource/1
POST /resources/1   =     POST /resource/1
...

Du bekommst das Bild. Niemand ist falsch, minimaler Aufwand, und der Kunde wird es immer richtig machen.

wynnset
quelle
1
Wenn Sie 302 Weiterleitungen durchführen und Ihr Cache alles zweimal speichert, haben Sie Ihren Cache falsch eingerichtet. Der Cache soll keine 302 Weiterleitungen speichern.
Wynnset
2
Wenn Ihr Client immer verwendet /resourcesund immer umgeleitet wird /resource, haben Sie es falsch gemacht. Wenn jemand anderes Ihre API verwendet, kann er entweder direkt die richtige URL verwenden oder umgeleitet werden (was funktioniert, aber falsch ist), und Sie haben den falschen Weg geöffnet.
Maaartinus
Ich bin mir nicht sicher, was du mit "falsch" meinst - das ist sehr subjektiv. Es ist nicht wirklich falsch, weil es funktioniert.
Wynnset
Dies erhöht die Wartungskosten, die Kosten für das Verständnis und die erforderliche Codemenge.
Will Sheppard
1

Ich mag es nicht, wenn sich der {id}Teil der URLs mit Unterressourcen überschneidet, da iddies theoretisch alles sein könnte und es Unklarheiten geben würde. Es werden verschiedene Konzepte (Bezeichner und Unterressourcennamen) gemischt.

Ähnliche Probleme werden oft in zu sehen enumKonstanten oder Ordnerstrukturen, in denen unterschiedliche Konzepte gemischt sind (zum Beispiel, wenn Sie Ordner haben Tigers, Lionsund Cheetahs, und dann auch ein Ordner mit dem Namen Animalsauf dem gleichen Niveau - das macht keinen Sinn , da man eine Teilmenge die ist andere).

Im Allgemeinen denke ich, dass der zuletzt genannte Teil eines Endpunkts singulär sein sollte, wenn er sich jeweils mit einer einzelnen Entität befasst, und plural, wenn er sich mit einer Liste von Entitäten befasst.

Endpunkte, die sich mit einem einzelnen Benutzer befassen:

GET  /user             -> Not allowed, 400
GET  /user/{id}        -> Returns user with given id
POST /user             -> Creates a new user
PUT  /user/{id}        -> Updates user with given id
DELETE /user/{id}      -> Deletes user with given id

Dann gibt es eine separate Ressource für die Abfrage von Benutzern, die im Allgemeinen eine Liste zurückgeben:

GET /users             -> Lists all users, optionally filtered by way of parameters
GET /users/new?since=x -> Gets all users that are new since a specific time
GET /users/top?max=x   -> Gets top X active users

Und hier einige Beispiele für eine Unterressource, die sich mit einem bestimmten Benutzer befasst:

GET /user/{id}/friends -> Returns a list of friends of given user

Machen Sie einen Freund (viele zu viele Link):

PUT /user/{id}/friend/{id}     -> Befriends two users
DELETE /user/{id}/friend/{id}  -> Unfriends two users
GET /user/{id}/friend/{id}     -> Gets status of friendship between two users

Es gibt niemals Mehrdeutigkeiten, und die Plural- oder Singularbenennung der Ressource ist ein Hinweis für den Benutzer, was er erwarten kann (Liste oder Objekt). Es gibt keine Einschränkungen für ids, die es theoretisch ermöglichen, einen Benutzer mit der ID zu haben, newohne sich mit einem (potenziellen zukünftigen) Subressourcennamen zu überschneiden.

john16384
quelle
1

Verwenden Sie Singular und nutzen Sie die englische Konvention, z. B. "Business Directory".

Viele Dinge lesen sich so: "Bücherregal", "Hundepaket", "Kunstgalerie", "Filmfestival", "Autolot" usw.

Dies entspricht bequem dem URL-Pfad von links nach rechts. Artikeltyp links. Stellen Sie den Typ rechts ein.

Ruft GET /userswirklich jemals eine Gruppe von Benutzern ab? Nicht gewöhnlich. Es ruft eine Reihe von Stubs ab, die einen Schlüssel und möglicherweise einen Benutzernamen enthalten. Also ist es /userssowieso nicht wirklich . Es ist ein Benutzerindex oder ein "Benutzerindex", wenn Sie so wollen. Warum nennst du es nicht so? Es ist ein /user/index. Da wir den Set-Typ benannt haben, können wir mehrere Typen haben, die unterschiedliche Projektionen eines Benutzers anzeigen, ohne auf Abfrageparameter zurückgreifen zu müssen, z . B. user/phone-listoder /user/mailing-list.

Und was ist mit User 300? Es ist immer noch /user/300.

GET /user/index
GET /user/{id}

POST /user
PUT /user/{id}

DELETE /user/{id}

Abschließend kann HTTP immer nur eine einzige Antwort auf eine einzelne Anfrage haben. Ein Pfad bezieht sich immer auf ein singuläres Etwas.

Samuel Danielson
quelle
-1

Für mich manipulieren Pluralformen die Sammlung , während Singulars den Gegenstand in dieser Sammlung manipulieren .

Die Sammlung ermöglicht die Methoden GET / POST / DELETE

Item erlaubt die Methoden GET / PUT / DELETE

Zum Beispiel

POST on / Schüler fügen einen neuen Schüler in die Schule ein.

DELETE on / Schüler entfernen alle Schüler in der Schule.

DELETE on / student / 123 entfernt Schüler 123 aus der Schule.

Es mag sich unwichtig anfühlen, aber einige Ingenieure vergessen manchmal den Ausweis. Wenn die Route immer plural war und ein LÖSCHEN ausführte, könnten Sie Ihre Daten versehentlich löschen. Wenn die ID auf dem Singular fehlt, wird eine 404-Route zurückgegeben, die nicht gefunden wurde.

Um das Beispiel weiter zu erweitern, wenn die API mehrere Schulen verfügbar machen sollte, dann so etwas wie

DELETE on / school / abc / students entfernt alle Schüler in der Schule abc.

Das richtige Wort zu wählen ist manchmal eine Herausforderung für sich, aber ich möchte die Pluralität für die Sammlung beibehalten. ZB cart_itemsoder cart/itemsfühlt sich richtig an. Im Gegensatz zum Löschen cartwird das Warenkorbobjekt selbst gelöscht und nicht die Artikel im Warenkorb;).

Ruralcoder
quelle
Sollte dies nicht aufgeteilt werden, ist / cart und / cart / item (s) trotzdem? Dann können Sie den gesamten Warenkorb (zB mit Löschen) oder einzelne Artikel adressieren?
Rob Grant
@RobertGrant Wäre das nicht "/ carts / items / 123"? (zB warum "Karren" und nicht "Karren" die Regel "immer Plural" ist?)
user2864740
1
Ich würde argumentieren, dass, wenn Produktionscode eingecheckt ist, der das Löschen aller Warenkorbartikel durchführen kann, es größere Probleme gibt als die Namenskonvention. Die Wahrscheinlichkeit, dass sie sich über einen Ausweis an ein 's' erinnern würden, ist viel geringer.
Andrew T Finnell
Würde jemand jemals einen Endpunkt erstellen, der einfach eine gesamte Sammlung löscht? Scheint mir extrem gefährlich zu sein und wahrscheinlich auch, warum REST Batch-Löschungen nicht wirklich unterstützt. (Sie müssten das Array in ein Objekt einschließen). Wenn ich unbedingt einen Endpunkt zum Löschen einer gesamten Sammlung benötigen würde, würde ich sicherstellen, dass der URI sehr, sehr eindeutig ist und definitiv nicht dem POST
cnps vom
-1

Wie wäre es mit:

/resource/(nicht /resource)

/resource/ bedeutet, dass es sich um einen Ordner handelt, der als "Ressource" bezeichnet wird. Es handelt sich um einen "Ressourcen" -Ordner.

Und ich denke auch, dass die Namenskonvention von Datenbanktabellen dieselbe ist, zum Beispiel ist eine Tabelle namens "Benutzer" eine "Benutzertabelle", sie enthält etwas, das "Benutzer" genannt wird.

chrisyue
quelle
-2

Ich bevorzuge die Verwendung von Plural ( /resources) und Singular ( /resource/{id}), da ich der Meinung bin, dass dies die Logik zwischen der Arbeit an der Sammlung von Ressourcen und der Arbeit an einer einzelnen Ressource klarer voneinander trennt.

Als wichtiger Nebeneffekt kann dies auch dazu beitragen, zu verhindern, dass jemand die API falsch verwendet. Stellen Sie sich beispielsweise den Fall vor, in dem ein Benutzer fälschlicherweise versucht, eine Ressource abzurufen, indem er die ID als folgenden Parameter angibt:

GET /resources?Id=123

In diesem Fall, wenn wir die Pluralversion verwenden, ignoriert der Server höchstwahrscheinlich den Parameter Id und gibt die Liste aller Ressourcen zurück. Wenn der Benutzer nicht aufpasst, glaubt er, dass der Anruf erfolgreich war, und verwendet die erste Ressource in der Liste.

Auf der anderen Seite, wenn Sie die Singularform verwenden:

GET /resource?Id=123

Der Server gibt höchstwahrscheinlich einen Fehler zurück, da die ID nicht richtig angegeben ist und der Benutzer feststellen muss, dass etwas nicht stimmt.

pberggreen
quelle
1
Warum mischst du hier Redewendungen? Sie verwenden die richtige URI-Notation im ersten Absatz und wechseln dann zu Abfrageparametern? Die Verwendung von Abfrageparametern zum Abrufen einer Ressource mit einer ID von 123 ist hier völlig falsch.
Andrew T Finnell
Das war eindeutig ein Fehler. Ich habe meine Antwort jetzt aktualisiert. Danke, dass du es bemerkt hast.
Pberggreen
Nachdem ich erneut herabgestimmt worden war, schaute ich mir an, was ich schrieb, und stellte fest, dass der ursprüngliche Beitrag korrekt war. Mein Punkt war genau, dass, wenn der Benutzer das Falsche tut, die Verwendung von Plural + Singular tatsächlich eine bessere Fehlermeldung ergibt als die Verwendung von Plural.
Pberggreen
Ich bin immer noch der Meinung, dass dies das vorliegende Problem verwirrt. Die Idee, Plural zu verwenden, ist, dass es eine Sammlung ist. Und die Nummer am Ende ist ein Index in der Sammlung. Was ist, wenn Sie / Ressource von selbst erhalten? Es ist ziemlich verwirrend, sowohl Plural als auch Singular zusammen zu verwenden. Sprichwort / resources / 123 sagt: Holen Sie sich meine Ressource 123 in den Ressourcen-Bucket.
Andrew T Finnell