REST: Gute Praktiken für das API-Design

Entwerfen Sie Ihre REST-API, damit sie verwendet wird

von Jay Kapadnis, Tempus Architect

Schlecht gestaltete REST-APIs = FRUSTRATION

Als Entwickler und Architekt von Tempus binde ich über REST viele Services ein. Manchmal finde ich es schwierig und zeitaufwendig, APIs zu integrieren / zu konsumieren, da das Design schlecht ist und nur wenig oder gar keine Dokumentation vorliegt. Dies führt dazu, dass Entwickler (und ich) vorhandene Dienste aufgeben und möglicherweise Funktionen duplizieren. Um diese Frustration zu vermeiden, ist das Entwicklungsteam von Hashmap bestrebt, bestimmte Standards und Spezifikationen einzuhalten, die in vorhandenen REST-Standards festgelegt sind.

Beginnen wir unsere Diskussion, indem wir zunächst verstehen, was REST ist und was mit dem Entwerfen von REST-APIs gemeint ist.

Was ist REST?

Im Jahr 2000 schlug Roy Fielding, einer der Hauptautoren der HTTP-Spezifikation, einen Architekturansatz für den Entwurf von Webdiensten vor, der als Representational State Transfer (REST) ​​bezeichnet wird.

Beachten Sie, dass REST nicht an HTTP gebunden ist, obwohl in diesem Artikel von einer REST-Implementierung mit dem HTTP-Protokoll ausgegangen wird. REST-APIs werden für eine „Ressource“ implementiert, die eine Entität oder ein Dienst sein kann. Diese APIs bieten die Möglichkeit, eine Ressource anhand ihres URI zu identifizieren, mit dem eine Darstellung des aktuellen Zustands einer Ressource über HTTP übertragen werden kann.

Warum ist API-Design so wichtig?

Die Leute stellen diese Frage ziemlich oft und um dies zu beantworten:

REST-APIs sind das Gesicht eines jeden Service und sollten daher:

1. Seien Sie einfach zu verstehen, damit die Integration unkompliziert ist
2. Gut dokumentiert sein, damit semantische Verhaltensweisen verstanden werden (nicht nur syntaktische)
3. Befolgen Sie akzeptierte Standards wie HTTP

Entwerfen und Entwickeln äußerst nützlicher REST-APIs

Bei der Entwicklung unserer REST-APIs befolgen wir bei Hashmap verschiedene Konventionen, um sicherzustellen, dass wir die oben aufgeführten Erwartungen an unsere Beschleunigerentwicklung und unsere Beratungsaufgaben erfüllen.

Diese Konventionen lauten wie folgt:

1. Verwenden Sie Substantive in URI

REST-APIs sollten für Ressourcen konzipiert sein, bei denen es sich um Entitäten oder Services usw. handeln kann. Daher müssen sie immer Substantive sein. Verwenden Sie beispielsweise / users anstelle von / createUser

2. Plural oder Singular

Im Allgemeinen bevorzugen wir die Verwendung von Pluralen, aber es gibt keine strenge Regel, nach der Singular als Ressourcenname nicht verwendet werden kann. Die Ideologie hinter der Verwendung von Pluralformen lautet:

Wir bearbeiten eine Ressource aus der Ressourcensammlung, um die von uns verwendete Sammlung im Plural darzustellen

Zum Beispiel im Fall von ...

GET / users / 123

Der Client fordert zum Abrufen einer Ressource aus der Benutzersammlung mit der ID 123 auf. Beim Erstellen einer Ressource möchten wir der aktuellen Ressourcensammlung eine Ressource hinzufügen. Die API sieht also wie folgt aus:

POST / Benutzer

3. Lassen Sie das HTTP-Verb Aktion definieren

Gemäß Punkt 1 sollten APIs nur Substantive für Ressourcen bereitstellen und die HTTP-Verben (GET, POST, PUT, DELETE) die Aktion definieren, die für eine Ressource ausgeführt werden soll.

Die folgende Tabelle fasst die Verwendung von HTTP-Verben zusammen mit APIs zusammen:

Tabelle 1: HTTP-Verben und Verwendung

4. Missbrauche keine sicheren Methoden (Idempotenz)

Sichere Methoden sind HTTP-Methoden, die unabhängig davon, wie oft der Client aufruft, dieselbe Ressourcendarstellung zurückgeben. GET-, HEAD-, OPTIONS- und TRACE-Methoden sind als sicher definiert, dh, sie dienen nur zum Abrufen von Daten und sollten den Status einer Ressource auf einem Server nicht ändern. Verwenden Sie GET nicht zum Löschen von Inhalten, zum Beispiel ...

GET / users / 123 / delete

Es ist nicht so, dass dies nicht implementiert werden kann, aber in diesem Fall wird die HTTP-Spezifikation verletzt.

Verwenden Sie HTTP-Methoden entsprechend der auszuführenden Aktion.

5. Stellen Sie die Ressourcenhierarchie über den URI dar

Wenn eine Ressource Unterressourcen enthält, stellen Sie sicher, dass dies in der API dargestellt wird, um es expliziter zu machen. Wenn ein Benutzer beispielsweise Beiträge hat und wir einen bestimmten Beitrag nach Benutzer abrufen möchten, kann die API als GET / users / 123 / posts / 1 definiert werden, wodurch der Beitrag mit der ID 1 nach Benutzer mit der ID 123 abgerufen wird

6. Versionieren Sie Ihre APIs

Durch die Versionierung von APIs wird stets die Abwärtskompatibilität eines Dienstes sichergestellt, während neue Features hinzugefügt oder vorhandene Funktionen für neue Clients aktualisiert werden. Es gibt verschiedene Denkansätze für die Version Ihrer API, aber die meisten von ihnen fallen unter zwei Kategorien:

Überschriften:

Es gibt zwei Möglichkeiten, wie Sie die Version in den Kopfzeilen angeben können:

Benutzerdefinierter Header:

Das Hinzufügen eines benutzerdefinierten X-API-VERSION-Headerschlüssels (oder eines beliebigen anderen Headers) durch den Client kann von einem Service verwendet werden, um eine Anforderung an den richtigen Endpunkt weiterzuleiten

Überschrift akzeptieren

Verwenden Sie die Überschrift accept, um Ihre Version anzugeben, z

=> Akzeptiere: application / vnd.hashmapinc.v2 + json

URL:

Betten Sie die Version in die URL ein, z

POST / v2 / Benutzer

Wir bevorzugen die Verwendung der URL-Methode für die Versionsverwaltung, da dadurch die Auffindbarkeit einer Ressource durch Betrachten der URL verbessert wird. Einige behaupten möglicherweise, die URL beziehe sich unabhängig von der Version auf dieselbe Ressource. Da sich die Darstellung der Antwort nach der Versionierung möglicherweise ändert oder nicht, warum sollte eine andere URL für dieselbe Ressource verwendet werden?

Ich befürworte hier nicht einen Ansatz gegenüber dem anderen, und letztendlich muss der Entwickler die bevorzugte Art der Versionsverwaltung auswählen.

7. Rückgabe der Vertretung

POST-, PUT- oder PATCH-Methoden, die zum Erstellen einer Ressource oder zum Aktualisieren von Feldern in einer Ressource verwendet werden, sollten immer eine aktualisierte Ressourcendarstellung als Antwort mit dem entsprechenden Statuscode zurückgeben, wie in den weiteren Punkten beschrieben.

POST, wenn das Hinzufügen einer neuen Ressource erfolgreich ist, sollte den HTTP-Statuscode 201 zusammen mit dem URI der neu erstellten Ressource im Location-Header (gemäß HTTP-Spezifikation) zurückgeben.

8. Filtern, Suchen und Sortieren

Erstellen Sie keine unterschiedlichen URIs zum Abrufen von Ressourcen mit Filtern, Suchen oder Sortieren von Parametern. Versuchen Sie, den URI einfach zu halten, und fügen Sie Abfrageparameter hinzu, um Parameter oder Kriterien zum Abrufen einer Ressource darzustellen (einzelner Ressourcentyp).

Filterung:

Verwenden Sie in URL definierte Abfrageparameter, um eine Ressource vom Server zu filtern. Wenn wir beispielsweise alle veröffentlichten Beiträge nach Benutzer abrufen möchten, können Sie eine API wie folgt entwerfen:

GET / users / 123 / posts? State = published

Im obigen Beispiel ist state der Filterparameter

Suche:

Um die Ergebnisse mit leistungsstarken Suchanfragen anstelle von einfachen Filtern zu erhalten, können Sie mehrere Parameter in einem URI verwenden, um das Abrufen einer Ressource vom Server anzufordern.

GET / users / 123 / posts? State = published & ta = scala

Die obige Abfrage sucht nach Beiträgen, die mit dem Scala-Tag veröffentlicht werden. Solr wird heutzutage häufig als Suchwerkzeug verwendet, da es erweiterte Funktionen für die Suche nach einem Dokument bietet und Sie Ihre API wie folgt gestalten können:

GET / users / 123 / posts? Q = sometext & fq = state: published, ta: scala

Dies durchsucht Posts nach freiem Text "sometext" (q) und filtert die Ergebnisse nach fq-Status wie veröffentlicht und mit dem Tag "Scala".

Sortierung:

ASC- und DESC-Sortierparameter können in URL übergeben werden, z.

GET / users / 123 / posts? Sort = -updated_at

Gibt Posts in absteigender Reihenfolge nach Aktualisierungsdatum und -zeit sortiert zurück.

9. HATEOAS

Hypermedia als Transfer Engine des Anwendungsstatus ist eine Einschränkung der REST-Anwendungsarchitektur, die sie von anderen Netzwerkanwendungsarchitekturen unterscheidet.

Es erleichtert die Navigation durch eine Ressource und die verfügbaren Aktionen. Auf diese Weise muss ein Client nicht wissen, wie er mit einer Anwendung für verschiedene Aktionen interagieren muss, da alle Metadaten in die Antworten vom Server eingebettet werden.

Um dies besser zu verstehen, sehen wir uns die folgende Antwort zum Abrufen des Benutzers mit der ID 123 vom Server an:

{
"Name": "John Doe",
"Links": [
{
"Rel": "self",
"Href": "http: // localhost: 8080 / users / 123"
},
{
"Rel": "posts",
"Href": "http: // localhost: 8080 / users / 123 / posts"
},
{
"Rel": "address",
"Href": "http: // localhost: 8080 / users / 123 / address"
}
]
}

Manchmal ist es einfacher, das Verknüpfungsformat zu überspringen und Verknüpfungen wie folgt als Felder einer Ressource anzugeben:

{
"Name": "John Doe",
"Self": "http: // localhost: 8080 / users / 123",
"Posts": "http: // localhost: 8080 / users / 123",
"Address": "http: // localhost: 8080 / users / 123 / address"
}

Es ist keine Konvention, die Sie jedes Mal befolgen müssen, da sie von den Ressourcenfeldern / -größen und den Aktionen abhängt, die für die Ressource ausgeführt werden können. Wenn Ressourcen mehrere Felder enthalten, die der Benutzer möglicherweise nicht durchgehen möchte, ist es eine gute Idee, die Navigation zu Unterressourcen anzuzeigen und dann HATEOAS zu implementieren.

10. Zustandslose Authentifizierung und Autorisierung

REST-APIs sollten zustandslos sein. Jeder Antrag sollte autark sein und muss ohne Kenntnis des vorherigen Antrags erfüllt werden. Dies geschieht im Fall der Autorisierung einer Benutzeraktion.

Bisher haben Entwickler Benutzerinformationen in serverseitigen Sitzungen gespeichert, was kein skalierbarer Ansatz ist. Aus diesem Grund sollte jede Anfrage alle Informationen eines Benutzers enthalten (sofern es sich um eine sichere API handelt), anstatt sich auf vorherige Anfragen zu verlassen.

Dies beschränkt APIs nicht auf einen Benutzer als autorisierte Person, da es auch die Autorisierung von Service zu Service ermöglicht. Für die Benutzerautorisierung bietet JWT (JSON Web Token) mit OAuth2 eine Möglichkeit, dies zu erreichen. Versuchen Sie außerdem, den verschlüsselten API-Schlüssel für die Kommunikation von Service zu Service im Header zu übergeben.

11. Prahlerei für Dokumentation

Swagger ist ein weit verbreitetes Tool zur Dokumentation von REST-APIs, mit dem die Verwendung einer bestimmten API untersucht werden kann, sodass Entwickler das zugrunde liegende semantische Verhalten verstehen können. Dies ist eine deklarative Methode zum Hinzufügen von Dokumentation mithilfe von Anmerkungen, die eine JSON generiert, die APIs und ihre Verwendung beschreibt.

Wir haben einen Maven-Archetyp erstellt, mit dem Sie hier beginnen können: Maven-Archetyp.

12. HTTP-Statuscodes

Verwenden Sie HTTP-Statuscodes, um die Antwort an einen Client zu senden. Es kann sich um eine Erfolgs- oder Fehlerantwort handeln, es sollte jedoch definiert werden, was der jeweilige Erfolg oder Fehler aus Serverperspektive bedeutet.

Nachfolgend sind die Kategorien von Antworten nach ihren Statuscodes aufgeführt:

2xx Erfolg

200 OK: Wird von einer erfolgreichen GET- oder DELETE-Operation zurückgegeben. PUT oder POST können dies auch verwenden, wenn der Dienst nach dem Erstellen oder Ändern keine Ressource an den Client zurückgeben möchte.

201 Erstellt: Antwort auf eine erfolgreiche Ressourcenerstellung durch eine POST-Anforderung.

3xx Umleitung

304 Nicht geändert: Wird verwendet, wenn der HTTP-Caching-Header implementiert ist.

4xx Client-Fehler

400 Bad Request: Wenn ein HTTP-Anforderungshauptteil nicht analysiert werden kann. Wenn eine API beispielsweise einen Text in einem JSON-Format für eine POST-Anforderung erwartet, der Text der Anforderung jedoch fehlerhaft ist.

401 Nicht autorisiert: Die Authentifizierung ist beim Zugriff auf die API nicht erfolgreich (oder es wurden keine Anmeldeinformationen angegeben).

403 Verboten: Wenn ein Benutzer nicht berechtigt ist, eine Aktion auszuführen, obwohl die Authentifizierungsinformationen korrekt sind.

404 Not Found: Wenn die angeforderte Ressource auf dem Server nicht verfügbar ist.

405 Methode nicht zulässig: Wenn der Benutzer versucht, einen API-Vertrag zu verletzen, z. B. eine Ressource mithilfe einer POST-Methode zu aktualisieren.

5xx Server Fehler

Diese Fehler treten aufgrund von Serverausfällen oder Problemen mit der zugrunde liegenden Infrastruktur auf.

Einpacken

Entwickler müssen einige Zeit mit dem Entwerfen von REST-APIs verbringen, da die API einen Dienst sehr benutzerfreundlich oder äußerst komplex machen kann. Darüber hinaus kann der Reifegrad der APIs mithilfe des Richardson-Reifegradmodells auf einfache Weise dokumentiert werden.

Wenn Sie Ihre Gedanken zur Integration mit REST-Diensten teilen und mehr darüber erfahren möchten, woran ich täglich bei Tempus arbeite, oder eine Demonstration planen möchten, wenden Sie sich bitte an mich unter jay.kapadnis@hashmapinc.com.

Teilen Sie Ihre Inhalte auf anderen Kanälen und informieren Sie sich über alle neuen Inhalte von Hashmap unter https://medium.com/hashmapinc.

Jay Kapadnis ist Tempus-Architekt bei Hashmap und arbeitet im branchenübergreifenden Engineering-Team mit einer Gruppe innovativer Technologen und Domain-Experten zusammen, die hochwertige Geschäftsergebnisse für unsere Kunden beschleunigen.