Entwerfen einer REST-API nach URI im Vergleich zu einer Abfragezeichenfolge

73

Angenommen, ich habe drei Ressourcen, die in etwa so zusammenhängen:

Grandparent (collection) -> Parent (collection) -> and Child (collection)

Das Obige zeigt die Beziehung zwischen diesen Ressourcen wie folgt: Jeder Großelternteil kann einem oder mehreren Elternteilen zugeordnet werden. Jedes Elternteil kann einem oder mehreren Kindern zuordnen. Ich möchte die Möglichkeit haben, die Suche anhand der untergeordneten Ressource zu unterstützen, aber mit den Filterkriterien:

Wenn meine Kunden mir einen Ausweis an einen Großelternteil weitergeben, möchte ich nur nach Kindern suchen, die direkte Nachkommen dieses Großelternteils sind.

Wenn meine Kunden mir einen ID-Verweis auf einen Elternteil übergeben, möchte ich nur nach Kindern suchen, die direkte Nachkommen meines Elternteils sind.

Mir ist so etwas eingefallen:

GET /myservice/api/v1/grandparents/{grandparentID}/parents/children?search={text}

und

GET /myservice/api/v1/parents/{parentID}/children?search={text}

für die oben genannten Anforderungen.

Aber ich könnte auch so etwas machen:

GET /myservice/api/v1/children?search={text}&grandparentID={id}&parentID=${id}

In diesem Entwurf konnte ich meinem Client gestatten, mir die eine oder andere Zeichenfolge in der Abfrage zu übergeben: entweder grandparentID oder parentID, aber nicht beide.

Meine Fragen sind:

1) Welches API-Design ist restvoller und warum? Sie meinen und verhalten sich semantisch gleich. Die letzte Ressource in der URI ist "untergeordnete Ressource". Dies bedeutet, dass der Client die untergeordnete Ressource verarbeitet.

2) Was sind die Vor- und Nachteile in Bezug auf die Verständlichkeit aus Sicht des Kunden und die Wartbarkeit aus Sicht des Designers?

3) Wofür werden Abfragezeichenfolgen wirklich verwendet, abgesehen vom "Filtern" Ihrer Ressource? Wenn Sie den ersten Ansatz wählen, wird der Filterparameter als Pfadparameter anstelle eines Abfragezeichenfolgenparameters in den URI selbst eingebettet.

Vielen Dank!

HiChews123
quelle
3
Der Titel Ihrer Frage sollte für jeden, der dies sieht, äußerst verwirrend sein. Die gültigen Segmente einer URI sind definiert als <Schema>: // <Benutzer>: <Kennwort> @ <Host>: <Port> / <Pfad>; <Parameter>? <Abfrage> / # <Fragment> (obwohl < password> ist veraltet) Eine "Abfragezeichenfolge" ist eine gültige Komponente einer URI, sodass Ihr "vs" im Titel verrückt ist.
K. Alan Bates
Meinst du I want to only search against children who are INdirect descendants of that grandparent.? Entsprechend Ihrer Struktur hat Großeltern keine direkten Kinder.
Null
Was ist der Unterschied zwischen einem Kind und einem Elternteil? Ist ein Elternteil ein Elternteil, wenn er keine Kinder hat? Gerüche eines Designfehlers
Pinoniq
Betreff: potential design flawund wenn Sie Informationen über eine Person, aber keine Informationen über deren Eltern haben, qualifizieren sie sich als child? (zB Adam und Eva) :)
Jesse Chisholm

Antworten:

64

Zuerst

Wie Per RFC 3986 § 3.4 (Uniform Resource Identifiers § (Syntax - Komponenten) | Abfrage

3.4 Abfrage

Die Abfragekomponente enthält nicht hierarchische Daten, die zusammen mit den Daten in der Pfadkomponente (Abschnitt 3.3) dazu dienen, eine Ressource im Rahmen des Schemas und der Benennungsberechtigung des URI (falls vorhanden) zu identifizieren.

Abfragekomponenten dienen zum Abrufen nicht hierarchischer Daten. Es gibt nur wenige Dinge, die hierarchischer sind als ein Stammbaum! Ergo - unabhängig davon, ob Sie es für "REST-y" halten oder nicht - um den Formaten, Protokollen und Frameworks von und für die Entwicklung von Systemen im Internet zu entsprechen, dürfen Sie diese Informationen nicht anhand der Abfragezeichenfolge identifizieren.

REST hat mit dieser Definition nichts zu tun.

Vor der Beantwortung Ihrer spezifischen Fragen ist Ihr Abfrageparameter "search" schlecht benannt. Besser wäre es, Ihr Abfragesegment als ein Wörterbuch von Schlüssel-Wert-Paaren zu behandeln.

Ihre Abfragezeichenfolge könnte besser definiert werden als

?first_name={firstName}&last_name={lastName}&birth_date={birthDate} usw.

Um Ihre spezifischen Fragen zu beantworten

1) Welches API-Design ist restvoller und warum? Sie meinen und verhalten sich semantisch gleich. Die letzte Ressource in der URI ist "untergeordnete Ressource". Dies bedeutet, dass der Client die untergeordnete Ressource verarbeitet.

Ich denke nicht, dass dies so eindeutig ist, wie Sie zu glauben scheinen.

Keine dieser Ressourcenschnittstellen ist REST-konform. Die Hauptvoraussetzung für die RESTful Architektur ist , dass Anwendungszustandsübergänge vom Server als hypermedia mitgeteilt werden müssen. Die Leute haben über die Struktur von URIs nachgedacht, um sie irgendwie zu "RESTful URIs" zu machen, aber die formale Literatur zu REST hat dazu eigentlich sehr wenig zu sagen. Meiner persönlichen Meinung nach wurde ein Großteil der Meta-Fehlinformationen zu REST veröffentlicht, um alte, schlechte Gewohnheiten zu brechen. (Ein wirklich "RESTful" -System aufzubauen ist eigentlich ein ziemlicher Arbeitsaufwand. Die Branche hat sich auf "REST" beschränkt und einige orthogonale Bedenken mit unsinnigen Qualifikationen und Einschränkungen hinterfragt.)

In der REST-Literatur heißt es, dass Sie, wenn Sie HTTP als Anwendungsprotokoll verwenden möchten, die formalen Anforderungen der Protokollspezifikationen einhalten müssen und nicht "http auf dem Laufenden halten und immer noch deklarieren können, dass Sie http verwenden". ; Wenn Sie URIs zur Identifizierung Ihrer Ressourcen verwenden, müssen Sie die formalen Anforderungen der Spezifikationen bezüglich URI / URLs einhalten.

Ihre Frage wird direkt in RFC3986 §3.4 angesprochen, das ich oben verlinkt habe. Unterm Strich in dieser Sache ist , dass , obwohl eine konforme URI ist unzureichend , um eine API „RESTful“ zu betrachten, wenn Sie Ihr System wirklich wollen , sein „RESTful“ und Sie sind mit HTTP und URIs, dann können Sie nicht hierarchischen Daten durch die Identifizierung Abfragezeichenfolge, weil:

3.4 Abfrage

Die Abfragekomponente enthält nicht hierarchische Daten

...So einfach ist das.

2) Was sind die Vor- und Nachteile in Bezug auf die Verständlichkeit aus Sicht des Kunden und die Wartbarkeit aus Sicht des Designers?

Die "Profis" der ersten beiden sind, dass sie auf dem richtigen Weg sind . Das "Gegenteil" des dritten ist, dass es völlig falsch zu sein scheint.

Soweit es Ihre Verständlichkeit und Wartbarkeit betrifft, sind diese definitiv subjektiv und hängen vom Verständnisniveau des Kundenentwicklers und den Designchips des Designers ab. Die URI-Spezifikation ist die endgültige Antwort darauf, wie URIs formatiert werden sollen. Hierarchische Daten sollen auf dem Pfad und mit Pfadparametern dargestellt werden. Nicht hierarchische Daten sollen in der Abfrage dargestellt werden. Das Fragment ist komplizierter, da seine Semantik speziell vom Medientyp der angeforderten Darstellung abhängt. Um die "Verständlichkeit" -Komponente Ihrer Frage anzusprechen, werde ich versuchen, genau zu übersetzen, was Ihre ersten beiden URIs tatsächlich sagen. Dann versuche ich darzustellen, was Sie mit gültigen URIs erreichen wollen.

Übersetzung Ihrer wörtlichen URIs in ihre semantische Bedeutung /myservice/api/v1/grandparents/{grandparentID}/parents/children?search={text} Dies besagt, dass die Eltern von Großeltern feststellen, dass ihr Kind das hat, search={text} was Sie mit Ihrer URI gesagt haben, nur dann schlüssig ist, wenn Sie nach den Geschwistern eines Großelternteils suchen. Mit Ihren "Großeltern, Eltern, Kindern" haben Sie herausgefunden, dass ein "Großelternteil" eine Generation zu ihren Eltern aufgestiegen ist und dann zu der "Großeltern" -Generation zurückgekehrt ist, indem Sie sich die Kinder der Eltern angesehen haben.

/myservice/api/v1/parents/{parentID}/children?search={text} Dies besagt, dass für die Eltern, die durch {parentID} identifiziert wurden, das Kind gefunden werden muss. ?search={text}Dies entspricht eher Ihren Vorstellungen und stellt eine Eltern-> Kind-Beziehung dar, die wahrscheinlich zum Modellieren Ihrer gesamten API verwendet werden kann. Um es auf diese Weise zu modellieren, muss der Kunde erkennen, dass, wenn er eine "grandparentId" hat, eine Indirektionsebene zwischen seiner ID und dem Teil des Familiendiagramms besteht, den er sehen möchte. Um ein "Kind" von "grandparentId" zu finden, können Sie Ihren /parents/{parentID}/childrenDienst anrufen und dann für jedes zurückgegebene Kind dessen Kinder nach Ihrer Personenkennung durchsuchen.

Implementierung Ihrer Anforderungen als URIs Wenn Sie eine erweiterbarere Ressourcenkennung modellieren möchten, die den Baum durchsuchen kann, können Sie dies auf verschiedene Arten erreichen.

1) Den ersten habe ich schon angedeutet. Stellen Sie das Diagramm "People" als zusammengesetzte Struktur dar. Jede Person hat einen Verweis auf die Generation über ihr über ihren Elternpfad und auf eine Generation unter ihr über ihren Kinderpfad.

/Persons/Joe/Parents/Mother/Parents wäre eine Möglichkeit, Joes Großeltern mütterlicherseits zu schnappen.

/Persons/Joe/Parents/Parents wäre eine Möglichkeit, alle Großeltern von Joe zu schnappen.

/Persons/Joe/Parents/Parents?id={Joe.GrandparentID} Ich würde Joes Großeltern mit der Kennung, die Sie in der Hand haben, packen.

und all dies wäre sinnvoll (beachten Sie, dass es hier je nach Aufgabe zu Leistungseinbußen kommen kann, wenn auf dem Server ein dfs erzwungen wird, da im Muster "Eltern / Eltern / Eltern" keine Zweigidentifikation vorhanden ist.) Sie profitieren auch von die Fähigkeit, eine beliebige Anzahl von Generationen zu unterstützen. Wenn Sie aus irgendeinem Grund 8 Generationen nachschlagen möchten, können Sie dies so darstellen

/Persons/Joe/Parents/Parents/Parents/Parents/Parents/Parents/Parents/Parents?id={Joe.NotableAncestor}

Dies führt jedoch zur zweiten dominanten Option für die Darstellung dieser Daten: über einen Pfadparameter.


2) Verwenden Sie Pfadparameter, um "die Hierarchie abzufragen". Sie könnten die folgende Struktur entwickeln, um die Belastung der Verbraucher zu verringern und dennoch eine sinnvolle API zu haben.

Um einen Blick auf 147 Generationen zu werfen, können Sie diesen Ressourcenbezeichner mit Pfadparametern darstellen

/Persons/Joe/Parents;generations=147?id={Joe.NotableAncestor}

Um Joe von seinem Urgroßelternteil ausfindig zu machen, können Sie in der Grafik eine bekannte Anzahl von Generationen nach Joe's Id durchsuchen. /Persons/JoesGreatGrandparent/Children;generations=3?id={Joe.Id}

Das Wichtigste bei diesen Ansätzen ist, dass Sie ohne weitere Informationen im Bezeichner und in der Anforderung erwarten sollten, dass der erste URI eine Person 147 Generationen von Joe mit dem Bezeichner Joe.NotableAncestor abruft. Sie sollten damit rechnen, dass der zweite Joe abruft. Angenommen, Sie möchten, dass Ihr aufrufender Client die gesamte Gruppe von Knoten und ihre Beziehungen zwischen der Stammperson und dem endgültigen Kontext Ihrer URI abrufen kann. Sie können dies mit demselben URI (mit einer zusätzlichen Dekoration) tun und text/vnd.graphvizauf Ihre Anforderung hin ein Akzeptieren von festlegen, bei dem es sich um den von der IANA registrierten Medientyp für die .dotDiagrammdarstellung handelt. Ändern Sie damit den URI in

/Persons/Joe/Parents;generations=147?id={Joe.NotableAncestor.Id}#directed

Wenn Accept: text/vnd.graphviz Sie einen HTTP-Anforderungsheader verwenden , können Sie Kunden ziemlich klar mitteilen lassen, dass sie den gerichteten Graphen der Generationshierarchie zwischen Joe und 147 Generationen vor der 147. Ahnengeneration haben möchten, die eine Person enthält, die als Joes "Bemerkenswerter Vorfahre" identifiziert wurde.

Ich bin mir nicht sicher, ob text / vnd.graphviz eine vordefinierte Semantik für das Fragment hat, bei der Suche nach Anweisungen konnte ich keine finden. Wenn dieser Medientyp tatsächlich vordefinierte Fragmentinformationen enthält, sollte seine Semantik befolgt werden, um eine konforme URI zu erstellen. Wenn diese Semantik jedoch nicht vordefiniert ist, gibt die URI-Spezifikation an, dass die Semantik des Fragmentbezeichners nicht eingeschränkt und stattdessen vom Server definiert ist, wodurch diese Verwendung gültig wird.


3) Wofür werden Abfragezeichenfolgen wirklich verwendet, abgesehen vom "Filtern" Ihrer Ressource? Wenn Sie den ersten Ansatz wählen, wird der Filterparameter als Pfadparameter anstelle eines Abfragezeichenfolgenparameters in den URI selbst eingebettet.

Ich glaube, ich habe dies bereits gründlich zu Tode geprügelt, aber Abfragezeichenfolgen dienen nicht zum "Filtern" von Ressourcen. Sie dienen zur Identifizierung Ihrer Ressource anhand nicht hierarchischer Daten. Wenn Sie Ihre Hierarchie mit Ihrem Pfad aufgeschlüsselt haben /person/{id}/children/und ein bestimmtes Kind oder eine bestimmte Gruppe von Kindern identifizieren möchten , verwenden Sie ein Attribut, das für die Gruppe gilt, die Sie identifizieren, und fügen Sie es in die Abfrage ein.

K. Alan Bates
quelle
1
Der RFC befasst sich nur mit Hierarchien, sofern er eine Syntax und einen Algorithmus zum Auflösen relativer URI-Referenzen definiert. Können Sie einige Quellen erläutern, warum die Beispiele im ursprünglichen Beitrag nicht übereinstimmen?
user2313838
2
Ist ein Stammbaum nicht wirklich ein Graph, kein Baum und überhaupt nicht hierarchisch? unter Berücksichtigung mehrerer Eltern, Scheidung und Wiederverheiratung usw.
Myster
1
@RobertoAloi Es erscheint mir nicht intuitiv, Ihre eigene "No Items Found" -Schnittstelle über ein leeres Set zu kommunizieren, wenn HTTP bereits eine Definition dafür hat. Das Grundprinzip ist, dass Sie den Server auffordern, "thing (s)" zurückzugeben, und wenn es keine "thing (s)" gibt, die zurückgegeben werden können, teilt der Server dies mit "404 - Not Found" (404 - Nicht gefunden) mit.
K. Alan Bates
1
Ich habe immer angenommen, dass 404 angibt, dass die Stamm-URL der Ressource nicht gefunden wurde, dh die Sammlung als Ganzes. Wenn Sie also nach / books? Author = Jim fragen und es keine Bücher von Jim gibt, erhalten Sie ein leeres Set []. Wenn Sie jedoch nach / articles? Author = Jim fragen, die Artikelressource jedoch noch nicht einmal als Sammlung 404 vorhanden ist, kann dies darauf hinweisen, dass die Suche nach Artikeln überhaupt keinen Sinn macht.
Adjenks
1
@adjenks Das hast du nicht aus formalen Vorgaben gelernt. Strukturell kann davon ausgegangen werden, dass die Bestandteile einer URL eine "Wurzel" enthalten, wenn dies Ihnen dabei hilft, über die Zwecke der Bestandteile zu urteilen. Letztendlich ist die Abfragezeichenfolge jedoch kein Anzeigefilter für eine über den Pfad identifizierte Ressource. Die Abfragezeichenfolge ist ein erstklassiger Bürger einer URL. Wenn Sie auf dem Server keine Ressourcen finden, die Ihrer URL entsprechen (einschließlich der Abfragezeichenfolge), ist 404 das in http definierte Mittel, um dies mitzuteilen. Das Interaktionsmodell, das Sie darstellen, führt eine Unterscheidung ohne Unterschied ein.
K. Alan Bates
14

Hier verstehst du es falsch:

Wenn meine Kunden mir einen Ausweis geben

In einem REST-System sollte der Client niemals mit IDs belästigt werden. Die einzigen Ressourcen-IDs, über die der Client Bescheid wissen sollte, sollten URIs sein. Dies ist das Prinzip der "einheitlichen Schnittstelle".

Überlegen Sie, wie Clients mit Ihrem System interagieren würden. Angenommen, der Benutzer beginnt, eine Liste von Großeltern zu durchsuchen, und er hat eines von Großelterns Kindern ausgewählt, zu dem er gebracht wird /grandparent/123. Wenn der Client in der Lage sein soll, die Kinder von zu suchen /grandparent/123, sollte laut "HATEOAS" das, was bei einer Abfrage /grandparent/123zurückgegeben wird, eine URL an die Suchoberfläche zurückgeben. Diese URL sollte bereits alle Daten enthalten, die zum Filtern nach dem aktuellen Großelternteil erforderlich sind.

Ob die Verbindung aussieht /grandparent/123?search={term}oder /parent?grandparent=123&search={term}oder /parent?grandparentTerm=someterm&someothergplocator=blah&search={term}sind inkonsequent nach REST. Beachten Sie, dass alle diese URLs dieselbe Anzahl von Parametern haben, {term}obwohl sie unterschiedliche Kriterien verwenden. Sie können zwischen diesen URLs wechseln oder sie vertauschen, abhängig von den jeweiligen Großeltern, und der Client würde nicht kaputt gehen, da die logische Beziehung zwischen den Ressourcen identisch ist, obwohl die zugrunde liegende Implementierung möglicherweise erheblich voneinander abweicht.

Wenn Sie den Dienst stattdessen so erstellt hätten, dass er erforderlich ist, /grandparent/{grandparentID}?search={term}wenn Sie in eine Richtung, aber in /children?parent={parentID}&search={term}eine andere Richtung gehen, wäre dies eine zu große Kopplung, da der Client wissen müsste, wie er verschiedene Dinge in verschiedene Relationen interpolieren muss, die konzeptionell ähnlich sind.

Ob Sie sich für /grandparent/123?search={term}oder entscheiden, /parent?grandparent=123&search={term}ist Geschmackssache und die Implementierung ist für Sie im Moment einfacher. Wichtig ist, dass der Client nicht geändert werden muss, wenn Sie Ihre URL-Strategie ändern oder unterschiedliche Strategien für unterschiedliche Eltern-Kind-Beziehungen verwenden.

Lüge Ryan
quelle
10

Ich bin mir nicht sicher, warum die Leute denken, dass das Einfügen der ID-Werte in die URL bedeutet, dass es sich irgendwie um eine REST-API handelt. Bei REST geht es darum, Verben zu handhaben und Ressourcen zu übergeben.

Wenn Sie also einen neuen Benutzer PUTEN möchten, müssen Sie einen angemessenen Datenblock senden, und eine POST-http-Anforderung ist ideal. Obwohl Sie also möglicherweise den Schlüssel (z. B. Benutzer-ID) senden, senden Sie die Benutzerdaten (zB Name, Adresse) als POST-Daten.

Nun ist es eine gebräuchliche Redewendung, die Ressourcen-ID in den URI einzufügen, aber dies ist mehr Konvention als jede Form von kanonischem "Nicht-REST, wenn es nicht im URI ist". Denken Sie daran, dass in der ursprünglichen These von REST http überhaupt nicht erwähnt wird, sondern eine Redewendung für den Umgang mit Daten in einem Client-Server ist, und keine Erweiterung von http (obwohl http natürlich unsere primäre Form der Implementierung von REST ist). .

Fielding verwendet beispielsweise die Anforderung einer wissenschaftlichen Arbeit als Beispiel. Sie möchten die Ressource "Dr. John's Paper zum Biertrinken" abrufen, möchten jedoch möglicherweise auch die ursprüngliche Version oder die neueste Version, sodass die Ressourcenkennung möglicherweise nicht als einzelne ID bezeichnet werden kann in der URI platziert. REST erlaubt dies und eine erklärte Absicht dahinter ist:

REST beruht stattdessen darauf, dass der Autor eine Ressourcenkennung auswählt, die am besten zur Art des identifizierten Konzepts passt

Es hindert Sie also nichts daran, einen statischen URI zum Abrufen Ihrer Eltern zu verwenden und einen Suchbegriff in der Abfragezeichenfolge einzugeben, um den genauen Benutzer zu identifizieren, nach dem Sie suchen. In diesem Fall ist die 'Ressource', die Sie identifizieren, die Gruppe der Großeltern (und daher enthält der URI 'Großeltern' als Teil des URI. REST enthält das Konzept der 'Kontrolldaten', mit denen bestimmt wird, welche Repräsentation Sie haben Die Ressource soll abgerufen werden - das Beispiel in dieser Datei ist die Cache-Kontrolle, aber auch die Versionskontrolle -, sodass meine Anfrage nach Dr. Johns exzellentem Artikel verfeinert werden kann, indem die Version als Kontrolldaten übergeben wird, die nicht Teil der URI sind.

Ich denke, ein Beispiel für eine REST-Schnittstelle, die normalerweise nicht erwähnt wird, ist SMTP . Beim Erstellen einer E-Mail-Nachricht senden Sie Verben (FROM, TO usw.) mit den Ressourcendaten für jeden Teil der E-Mail-Nachricht. Dies ist RESTful, obwohl es keine http-Verben verwendet, sondern einen eigenen Satz.

Also ... während Sie eine Ressourcenidentifikation in Ihrer URI haben müssen, muss es nicht Ihre ID-Referenz sein. Dies kann gerne als Steuerdaten, in der Abfragefolge oder sogar in POST-Daten gesendet werden. Was Sie in Ihrer REST-API wirklich identifizieren, ist, dass Sie nach einem Kind suchen, das Sie bereits in Ihrer URI haben.

Wenn Sie die Definition von REST lesen, fordern Sie meines Erachtens eine untergeordnete Ressource an und übergeben Steuerdaten (in Form einer Abfragezeichenfolge), um zu bestimmen, welche zurückgegeben werden soll. Infolgedessen können Sie keine URI-Anforderung für einen Großelternteil oder einen Elternteil stellen. Wenn Sie möchten, dass Kinder zurückgegeben werden, sollte der Begriff Eltern / Großeltern oder ID definitiv nicht in einer solchen URI enthalten sein. Kinder sollten sein.

gbjbaanb
quelle
Tatsächlich ist URI als Konzept von zentraler Bedeutung für REST. Was jedoch nicht so wichtig ist, ist die URI-Syntax. Eine ordnungsgemäße REST-Schnittstelle muss Ressourcen mit einer gemeinsamen Syntax identifizieren. Auf der Grundlage des REST-Prinzips ist es nicht unbedingt schlecht, komplexe Ressourcen mit einem JSON-Objekt anstelle des RFC 3986-URI zu identifizieren. In diesem Fall sollten Sie jedoch JSON RI für Ihre gesamte API verwenden.
Lie Ryan
4

Viele Leute haben bereits darüber gesprochen, was REST bedeutet, usw. usw. Aber keine scheint das eigentliche Problem anzugehen: Ihr Design.

Warum unterscheidet sich Großeltern von Vätern? Beide haben Kinder, die möglicherweise Kinder haben können, die ...

Schließlich sind sie alle "menschlich". Sie haben das wahrscheinlich auch in Ihrem Code. Also benutze das:

GET /<api-endpoint>/humans/<ID>

Gibt einige nützliche Informationen über den Menschen zurück. (Name und so)

GET /<api-endpoint>/humans/<ID>/children

wird offensichtlich eine Reihe von Kindern zurückgeben. Wenn keine Kinder vorhanden sind, ist wahrscheinlich ein leeres Array der richtige Weg.

Um dies zu vereinfachen, können Sie beispielsweise das Flag 'hasChildren' hinzufügen. oder 'hasGrandChildren'.

Denken Sie schlauer und nicht härter

Pinoniq
quelle
1

Das Folgende ist mehr RESTfull, da jede Großeltern-ID eine eigene URL erhält. Auf diese Weise wird die Ressource auf einzigartige Weise identifiziert.

GET /myservice/api/v1/grandparents/{grandparentID}
GET /myservice/api/v1/grandparents/{grandparentID}/parents/children?search={text}

Die Suche nach Abfrageparametern ist eine gute Möglichkeit, eine Suche im Kontext dieser Ressource auszuführen.

Wenn eine Familie sehr groß wird, können Sie start / limit als Abfrageoptionen verwenden, zum Beispiel:

GET /myservice/api/v1/grandparents/{grandparentID}/children?start=1&limit=50

Als Entwickler ist es gut, verschiedene Ressourcen mit einer eindeutigen URL / URI zu haben. Ich denke, Sie sollten Abfrageparameter nur verwenden, wenn sie auch weggelassen werden könnten.

Vielleicht ist dies eine gute Lektüre http://www.thoughtworks.com/insights/blog/rest-api-design-resource-modeling und ansonsten die originale Doktorarbeit von Roy T Fielding https://www.ics.uci.edu /~fielding/pubs/dissertation/fielding_dissertation.pdf , das die Konzepte sehr gut und vollständig erklärt.

l.renkema
quelle
1

Ich gehe mit

/myservice/api/v1/people/{personID}/descendants/2?search={text}

In diesem Fall ist jedes Präfix eine gültige Ressource:

  • /myservice/api/v1/people: Alle Personen
  • /myservice/api/v1/people/{personID}: eine Person mit vollständigen Informationen (einschließlich Vorfahren, Geschwister, Nachkommen)
  • /myservice/api/v1/people/{personID}/descendants: die Nachkommen einer Person
  • /myservice/api/v1/people/{personID}/descendants/2: Enkel einer Person

Ist vielleicht nicht die beste Antwort, macht aber zumindest Sinn für mich.

laike9m
quelle
-1

Viele vor mir haben bereits darauf hingewiesen, dass das URL-Format im Kontext von RESTful Service keine Rolle spielt ... meine beiden Cent wären ... ein wichtiger Aspekt von REST, wie er in der ursprünglichen Beschreibung befürwortet wurde, war das Konzept von "Ressourcen". .wenn Sie Ihre URL entwerfen, müssen Sie möglicherweise berücksichtigen, dass eine "Ressource" keine Zeile in einer einzelnen Tabelle ist (obwohl dies möglich ist). Es handelt sich vielmehr um eine Darstellung. Das ist auch konsistent. .und kann verwendet werden, um Änderungen am Status dieser Repräsentation (und effektiv am untergeordneten Speichermedium) vorzunehmen. Und eine bestimmte Ressource ist möglicherweise nur in Ihrem Geschäftskontext von Bedeutung.

In deinem Beispiel / myservice / api / v1 / großeltern / {großelternID} / eltern / kinder? Search = {text}

Könnte eine sinnvollere Ressource sein, wenn Sie / myservice / api / v1 / siblingsOfGrandParents kürzen? Search = ..

In diesem Fall können Sie 'siblingsOfGrandParents' als Ressource deklarieren. Dies vereinfacht die URL

Wie andere wiesen darauf hin, gibt es eine weit verbreitete falsche Vorstellung, dass Sie in jeder Art von hierarchischer Beziehung zwischen Domänenobjekten in expliziterer Form in eine URL passen müssen. Es gibt keine feste Regel für eine 1-zu-1-Zuordnung zwischen Domänenobjekten und Ressourcen und repräsentieren alle ihre Beziehungen ... die Frage sollte eher sein, ich glaube ... besteht die Notwendigkeit, eine solche Beziehung über URLs aufzudecken ... speziell Pfadsegmente ... vielleicht nicht.

Senthu Sivasambu
quelle
Wenn Sie Ihre kostbare Zeit damit verbringen, eine Antwort herunterzustufen, ist es hilfreich, wenn Sie Ihre Gründe ansprechen und angeben können.
Senthu Sivasambu
Ich bin mir nicht ganz sicher, warum ich aufgrund Ihrer Antwort herabgestimmt habe. Ich stimme mit Ihnen ein. Ein paar unmittelbare Dinge, die mir auffallen, sind, dass Sie ein leicht tangentiales Beispiel geliefert haben, indem Sie "Geschwister" erwähnt haben, als das OP nach hierarchischen Beziehungen fragte. Vielleicht könnte auch Ihr Schreibstil verbessert werden. Sie verwenden viel "...", wir verwenden "..." im formellen, professionellen oder anleitenden Schreiben eher nicht. Es gibt auch ein bisschen Redundanz (z. B. erwähnen Sie zum Beispiel, dann sagen Sie in Ihrem Beispiel). Vielleicht könnte Ihre Antwort präziser und direkter auf die Frage des OP eingehen.
KennyCason