Soweit ich das beurteilen kann, sollte jede einzelne Ressource nur einen kanonischen Pfad haben. Was wären im folgenden Beispiel gute URL-Muster?
Nehmen Sie als Beispiel eine Restrepräsentation von Unternehmen. In diesem hypothetischen Beispiel kann jedes Unternehmen besitzt 0 oder mehr Abteilungen und jede Abteilung besitzt 0 oder mehr Beschäftigten.
Eine Abteilung kann ohne ein verbundenes Unternehmen nicht existieren .
Ein Mitarbeiter kann ohne eine zugehörige Abteilung nicht existieren .
Jetzt würde ich die natürliche Darstellung der Ressourcenmuster finden.
/companies
Eine Sammlung von Unternehmen - Akzeptiert Put für ein neues Unternehmen. Holen Sie sich für die gesamte Sammlung./companies/{companyId}
Ein individuelles Unternehmen. Akzeptiert GET, PUT und DELETE/companies/{companyId}/departments
Akzeptiert POST für einen neuen Artikel. (Erstellt eine Abteilung innerhalb des Unternehmens.)/companies/{companyId}/departments/{departmentId}/
/companies/{companyId}/departments/{departmentId}/employees
/companies/{companyId}/departments/{departmentId}/employees/{empId}
Angesichts der Einschränkungen in jedem der Abschnitte halte ich dies für sinnvoll, wenn es etwas tief verschachtelt ist.
Meine Schwierigkeit tritt jedoch auf, wenn ich GET
alle Mitarbeiter in allen Unternehmen auflisten möchte .
Das Ressourcenmuster dafür würde am ehesten /employees
(Die Sammlung aller Mitarbeiter) zugeordnet.
Bedeutet das, dass ich es /employees/{empId}
auch haben sollte, denn wenn ja, dann gibt es zwei URIs, um dieselbe Ressource zu erhalten?
Oder vielleicht sollte das gesamte Schema abgeflacht werden, aber das würde bedeuten, dass Mitarbeiter ein verschachteltes Objekt der obersten Ebene sind.
Auf einer grundlegenden Ebene wird /employees/?company={companyId}&department={deptId}
genau die gleiche Ansicht der Mitarbeiter zurückgegeben wie das am tiefsten verschachtelte Muster.
Was ist die beste Praxis für die URL - Muster , bei denen Ressourcen im Besitz von anderen Ressourcen , sondern separat Abfrage-fähig sein?
quelle
Antworten:
Was Sie getan haben, ist richtig. Im Allgemeinen kann es mehrere URIs für dieselbe Ressource geben - es gibt keine Regeln, die besagen, dass Sie dies nicht tun sollten.
Und im Allgemeinen müssen Sie möglicherweise direkt oder als Teilmenge von etwas anderem auf Elemente zugreifen - daher ist Ihre Struktur für mich sinnvoll.
Nur weil Mitarbeiter unter Abteilung erreichbar sind:
company/{companyid}/department/{departmentid}/employees
Das bedeutet nicht, dass sie auch unter Unternehmen nicht zugänglich sind:
company/{companyid}/employees
Welches würde Mitarbeiter für dieses Unternehmen zurückgeben. Es hängt davon ab, was Ihr konsumierender Kunde benötigt - dafür sollten Sie entwerfen.
Ich würde jedoch hoffen, dass alle URL-Handler denselben Hintergrundcode verwenden, um die Anforderungen zu erfüllen, damit Sie keinen Code duplizieren.
quelle
/company/3/department/2/employees/1
). Wenn die API Möglichkeiten zum Abrufen jeder Ressource bietet, kann jede dieser Anforderungen entweder in einer clientseitigen Bibliothek oder als einmaliger Endpunkt erfolgen, der Code wiederverwendet./company/*
sollte nur die Unternehmensressource zurückgegeben und der Ressourcentyp überhaupt nicht geändert werden. Nichts davon wird von REST spezifiziert - es ist im Allgemeinen eine schlecht spezifizierte - nur persönliche Präferenz.Ich habe beide Entwurfsstrategien ausprobiert - verschachtelte und nicht verschachtelte Endpunkte. Ich habe das gefunden:
Wenn die verschachtelte Ressource einen Primärschlüssel hat und Sie keinen übergeordneten Primärschlüssel haben, müssen Sie ihn für die verschachtelte Struktur abrufen, obwohl das System ihn tatsächlich nicht benötigt.
Verschachtelte Endpunkte erfordern normalerweise redundante Endpunkte. Mit anderen Worten, Sie benötigen häufig den zusätzlichen Endpunkt / Mitarbeiter, damit Sie eine abteilungsübergreifende Liste der Mitarbeiter erhalten. Wenn Sie / Mitarbeiter haben, was genau kaufen Sie / Unternehmen / Abteilungen / Mitarbeiter?
Verschachtelungsendpunkte entwickeln sich nicht so gut. Beispielsweise müssen Sie jetzt möglicherweise nicht nach Mitarbeitern suchen, aber möglicherweise später. Wenn Sie eine verschachtelte Struktur haben, haben Sie keine andere Wahl, als einen weiteren Endpunkt hinzuzufügen. Bei einem nicht verschachtelten Design fügen Sie einfach weitere Parameter hinzu, was einfacher ist.
Manchmal kann eine Ressource mehrere Arten von Eltern haben. Dies führt zu mehreren Endpunkten, die alle dieselbe Ressource zurückgeben.
Redundante Endpunkte erschweren das Schreiben der Dokumente und das Erlernen der API.
Kurz gesagt, das nicht verschachtelte Design scheint ein flexibleres und einfacheres Endpunktschema zu ermöglichen.
quelle
Ich habe das, was ich getan habe, von der Frage zu einer Antwort verschoben, bei der wahrscheinlich mehr Menschen es sehen werden.
Was ich getan habe, ist, die Erstellungsendpunkte am verschachtelten Endpunkt zu haben. Der kanonische Endpunkt zum Ändern oder Abfragen eines Elements befindet sich nicht in der verschachtelten Ressource .
In diesem Beispiel (nur die Endpunkte auflisten, die eine Ressource ändern)
POST
/companies/
Wenn Sie eine neue Firma erstellen, wird ein Link zur erstellten Firma zurückgegeben.POST
/companies/{companyId}/departments
Wenn eine Abteilung erstellt wird, gibt die neue Abteilung einen Link zu zurück/departments/{departmentId}
PUT
/departments/{departmentId}
ändert eine AbteilungPOST
/departments/{deparmentId}/employees
Erstellt einen neuen Mitarbeiter, der einen Link zurückgibt/employees/{employeeId}
Es gibt also Ressourcen auf Stammebene für jede der Sammlungen. Das Erstellen befindet sich jedoch im Besitzobjekt .
quelle
POST
Bedeutung benutztPUT
und sonst.Ich habe alle oben genannten Antworten gelesen, aber es scheint, dass sie keine gemeinsame Strategie haben. Ich habe in Microsoft Documents einen guten Artikel über Best Practices in der Design-API gefunden . Ich denke, Sie sollten sich beziehen.
.
quelle
Wie Ihre URLs aussehen, hat nichts mit REST zu tun. Alles geht. Es ist eigentlich ein "Implementierungsdetail". So wie Sie Ihre Variablen benennen. Alles was sie sein müssen ist einzigartig und langlebig.
Verschwenden Sie nicht zu viel Zeit damit, treffen Sie einfach eine Wahl und bleiben Sie dabei / seien Sie konsequent. Wenn Sie beispielsweise mit Hierarchien arbeiten, tun Sie dies für alle Ihre Ressourcen. Wenn Sie mit Abfrageparametern ... usw. arbeiten, genau wie Namenskonventionen in Ihrem Code.
Warum so? Soweit ich weiß, soll eine "RESTful" -API durchsuchbar sein (Sie wissen ... "Hypermedia als Engine des Anwendungsstatus"), daher kümmert sich ein API-Client nicht darum, wie Ihre URLs aussehen, solange sie sind gültig (es gibt keine Suchmaschinenoptimierung, keinen Menschen, der diese "freundlichen URLs" lesen muss, außer möglicherweise zum Debuggen ...)
Wie schön / verständlich eine URL in einer REST-API ist, ist nur für Sie als API-Entwickler interessant, nicht für den API-Client, wie es der Name einer Variablen in Ihrem Code wäre.
Das Wichtigste ist, dass Ihr API-Client weiß, wie Sie Ihren Medientyp interpretieren. Zum Beispiel weiß es, dass:
Unten finden Sie ein Beispiel für einen HTTP-Austausch (Körper befinden sich in Yaml, da das Schreiben einfacher ist):
Anfrage
Antwort: Eine Liste mit Links zur Hauptressource (Unternehmen, Personen, was auch immer ...)
Anfrage: Link zu Unternehmen (unter Verwendung der body.links.companies der vorherigen Antwort)
Antwort: Eine unvollständige Liste von Unternehmen (unter Elementen). Die Ressource enthält verwandte Links, z. B. einen Link, mit dem die nächsten Unternehmen (body.links.next) einen anderen (mit Vorlagen versehenen) Link zur Suche erhalten (body.links.search).
Wie Sie sehen, hat die Art und Weise, wie Sie den Pfadteil Ihrer URLs strukturieren, für Ihren API-Client keinen Wert. Und wenn Sie Ihrem Kunden die Struktur Ihrer URLs als Dokumentation mitteilen, führen Sie kein REST durch (oder zumindest nicht Level 3 gemäß " Richardson's Reifegradmodell ").
quelle
Ich bin mit dieser Art von Weg nicht einverstanden
Wenn Sie Abteilungen erhalten möchten, ist es meiner Meinung nach besser, eine / Abteilungen-Ressource zu verwenden
Ich nehme an, Sie haben eine
companies
Tabelle und einedepartments
Tabelle, dann Klassen, um sie in der von Ihnen verwendeten Programmiersprache abzubilden. Ich gehe auch davon aus, dass Abteilungen anderen Entitäten als Unternehmen zugeordnet werden können. Daher ist eine / abteilungsressource unkompliziert, es ist praktisch, Ressourcen Tabellen zuzuordnen, und Sie benötigen nicht so viele Endpunkte, da Sie sie wiederverwenden könnenzum Beispiel für jede Art von Suche
Wenn Sie eine Abteilung erstellen möchten, wird die
Die Ressource sollte verwendet werden und der Anforderungshauptteil sollte die Firmen-ID enthalten (wenn die Abteilung nur mit einer Firma verknüpft werden kann).
quelle
GET /companies/{companyId}?include=departments
da dadurch sowohl das Unternehmen als auch seine Abteilungen in einer einzigen HTTP-Anforderung abgerufen werden können. Fractal macht das wirklich gut./departments
Endpunkt so einschränken , dass nur ein Administrator darauf zugreifen kann, und jedes Unternehmen nur über `/ company / {companyId} / department` auf seine eigenen Abteilungen zugreifen lassenRails bietet hierfür eine Lösung: flache Verschachtelung .
Ich denke, das ist gut so, denn wenn Sie direkt mit einer bekannten Ressource arbeiten, müssen Sie keine verschachtelten Routen verwenden, wie in anderen Antworten hier erläutert wurde.
quelle