Suche…


Bemerkungen

In diesem Abschnitt erhalten Sie einen Überblick über den Rest und warum ein Entwickler sie verwenden möchte.

Es sollte auch alle großen Themen in Ruhe erwähnen und auf die verwandten Themen verweisen. Da die Dokumentation für den Rest neu ist, müssen Sie möglicherweise erste Versionen dieser verwandten Themen erstellen.

REST-Übersicht

REST steht für Präsentations - S tate T ransfer RE und wurde von Roy Fielding in seiner Doktorarbeit geprägt Baustile und das Design von Netzwerk-basierten Software - Architekturen . Darin identifiziert er spezifische architektonische Prinzipien wie:

  • Adressierbare Ressourcen: Die wichtigste Abstraktion von Informationen und Daten in REST ist eine Ressource, und jede Ressource muss über einen URI adressierbar sein.

  • Eine einheitliche, eingeschränkte Schnittstelle: Verwenden Sie eine kleine Anzahl gut definierter Methoden, um unsere Ressourcen zu manipulieren.

  • Darstellungsorientiert: Eine Ressource, auf die ein URI verweist, kann unterschiedliche Formate haben und unterschiedliche Plattformen benötigen unterschiedliche Formate. Beispielsweise benötigen Browser HTML, JavaScript erfordert JSON- und Java-Anwendungen möglicherweise XML, JSON, CSV, Text usw. Daher interagieren wir mit Diensten Verwendung der Darstellung dieses Dienstes.

  • Kommunizieren Sie zustandslos: Zustandslose Anwendungen sind einfacher zu skalieren.

  • Hypermedia als Engine of Application State: Lassen Sie unsere Datenformate Zustandsübergänge in unseren Anwendungen steuern.

Der Satz dieser architektonischen Prinzipien wird als REST bezeichnet. Die Konzepte von REST sind von denen von HTTP inspiriert. Roy Fielding, der uns REST gegeben hat, ist auch einer der Autoren von HTTP-Spezifikationen.

Web Services und RESTful Web Services sind Dienste, die dem Internet für programmgesteuerte Zugriffe ausgesetzt sind. Sie sind Online-API, die wir mit unserem Code aufrufen können. Es gibt zwei Arten von "großen" Web-Services, SOAP- und REST-Web-Services.

RESTful Web Services : Web Services, die unter Verwendung der REST-Architekturkonzepte geschrieben werden, werden als RESTful Web Services bezeichnet. Sie konzentrieren sich auf Systemressourcen und darauf, wie der Status einer Ressource über das HTTP-Protokoll an verschiedene Clients übertragen werden kann.

Dieses Dokument konzentriert sich ausschließlich auf RESTful-Webdienste, daher werden wir nicht auf die Details von SOAP WS eingehen.

Es gibt keine strengen Regeln beim Entwurf von RESTful-Webservices wie

  • Kein Protokollstandard
  • Kein Standard für Kommunikationskanäle
  • Kein Service-Definitionsstandard

Aber für all diese gelten für SOAP strenge Regeln. Alle SOAP-Webdienste folgen der SOAP-Spezifikation, in der festgelegt ist, was jeder SOAP-Webdienst sein soll. Diese Spezifikation wird von einem Komitee entwickelt und verwaltet. Wenn SOAP WS nicht einmal einer einzigen Regel folgt, handelt es sich definitionsgemäß nicht um SOAP.

Konzepte von RESTful Web Services

Es gibt einige Richtlinien, die beim Entwerfen / Entwickeln von RESTful-API zu beachten sind:

  1. Ressourcenbasierte Standorte / URI
  2. Ordnungsgemäße Verwendung von HTTP-Methoden
  3. HATEOAS (Hypermedia als Engine of Application State)

Der Hauptansatz bei der Entwicklung von RESTful-APIs sollte darin bestehen, die API so "RESTful wie möglich" zu machen.

REST über HTTP

REST ist eine protokollagnostische Architektur, die von Roy Fielding in seiner Dissertation vorgeschlagen wurde (Kapitel 5 ist die Präsentation von REST) ​​und verallgemeinert das bewährte Konzept von Webbrowsern als Clients, um Clients in einem verteilten System von Servern zu entkoppeln.

Damit ein Dienst oder eine API REST-fähig ist, muss er sich an die folgenden Einschränkungen halten:

  • Kundenserver
  • Staatenlos
  • Zwischenspeicherbar
  • Schichtsystem
  • Einheitliche Schnittstelle
    • Ressourcenidentifikation
    • Darstellung der Ressourcen
    • Selbstbeschreibende Nachrichten
    • Hypermedia

Neben den in Fieldings Dissertation genannten Einschränkungen müssen die REST-APIs in seinem Blogbeitrag hypertextgesteuert sein . Fielding hat klargestellt, dass das Aufrufen eines Dienstes über HTTP ihn nicht RESTful macht . Ein Dienst sollte daher auch weitere Regeln beachten, die wie folgt zusammengefasst werden:

  • Die API sollte das zugrunde liegende Protokoll einhalten und nicht gegen dieses verstoßen. Obwohl REST meistens über HTTP verwendet wird, ist es nicht auf dieses Protokoll beschränkt.

  • Starker Fokus auf Ressourcen und deren Darstellung über Medientypen.

  • Kunden sollten nicht über erste Kenntnisse oder Annahmen zu den verfügbaren Ressourcen oder deren zurückgegebenen Status ( "typisierte" Ressource ) in einer API verfügen, sondern diese über ausgegebene Anforderungen und analysierte Antworten direkt lernen. Dies gibt dem Server die Möglichkeit, Ressourcen zu verschieben oder umzubenennen, ohne die Client-Implementierung zu beschädigen.

Richardson Reifemodell

Mit dem Richardson Maturity Model können REST-Einschränkungen über HTTP angewendet werden, um RESTful-Webdienste zu erhalten.

Leonard Richardson hat die Anwendungen in diese 4 Schichten unterteilt:

  • Stufe 0: Verwendung von HTTP für den Transport
  • Stufe 1: Verwendung von URL zur Identifizierung von Ressourcen
  • Stufe 2: Verwendung von HTTP-Verben und -Status für die Interaktionen
  • Stufe 3: Verwendung von HATEOAS

Da der Fokus auf der Repräsentation des Status einer Ressource liegt, wird die Unterstützung mehrerer Repräsentationen für dieselbe Ressource empfohlen. Eine Darstellung kann daher einen Überblick über den Ressourcenzustand bieten, während eine andere Person die vollständigen Details derselben Ressource zurückgibt.

Beachten Sie auch, dass eine API bei Fielding-Einschränkungen erst dann effektiv REST-fähig ist, wenn die 3. Ebene des RMM implementiert ist .


HTTP-Anfragen und Antworten

Eine HTTP-Anfrage lautet:

  • Ein Verb (aka-Methode), meistens eines von GET , POST , PUT , DELETE oder PATCH
  • Eine URL
  • Header (Schlüssel-Wert-Paare)
  • Optional ein Body (auch bekannt als Payload, Daten)

Eine HTTP-Antwort lautet:

Eigenschaften der HTTP-Verben:

  • Verben, die einen Körper haben: POST , PUT , PATCH
  • Verben, die sicher sein müssen (dh Ressourcen dürfen nicht verändert werden): GET
  • Verben, die idempotent sein müssen (dh, sie dürfen Ressourcen nicht erneut beeinträchtigen, wenn sie mehrfach ausgeführt werden): GET (nullipotent), PUT , DELETE
        body  safe  idempotent
GET      ✗     ✔     ✔
POST     ✔     ✗     ✗
PUT      ✔     ✗     ✔
DELETE   ✗     ✗     ✔
PATCH    ✔     ✗     ✗

Folglich können HTTP-Verben mit den CRUD-Funktionen verglichen werden :

Beachten Sie, dass eine PUT Anforderung die Clients PUT , die gesamte Ressource mit den aktualisierten Werten zu senden . Um eine Ressource teilweise zu aktualisieren, kann ein PATCH Verb verwendet werden (siehe Teilweise Aktualisierung einer Ressource? ).

Übliche HTTP-Antwortstatus

Erfolg

Umleitung

Kundenfehler

Serverfehler

Anmerkungen

Nichts hindert Sie daran, einen Körper zu falschen Antworten hinzuzufügen, um die Ablehnung für die Kunden klarer zu machen. Zum Beispiel ist die 422 (UNPROCESSABLE ENTITY) etwas vage: Der Antworttext sollte den Grund dafür angeben, warum die Entität nicht verarbeitet werden konnte.


HATEOAS

Jede Ressource muss Hypermedia für die Ressourcen bereitstellen, mit denen sie verknüpft ist. Ein Link besteht mindestens aus:

  • A rel (für rel ation, aka name): beschreibt die Beziehung zwischen der Hauptressource und der verknüpften Ressource.
  • A href : Die URL für die verknüpften Ressourcen.

Zusätzliche Attribute können auch verwendet werden, um bei der Abwertung, beim Aushandeln von Inhalten usw. zu helfen.

Cormac Mulhall erklärt, dass der Client entscheiden sollte, welches HTTP-Verb verwendet werden soll, je nachdem, was er versucht . Im Zweifelsfall sollte die API-Dokumentation Ihnen trotzdem helfen, die verfügbaren Interaktionen mit allen Hypermedien zu verstehen.


Medientypen

Medientypen helfen, selbstbeschreibende Meldungen zu erhalten. Sie spielen die Rolle des Vertrages zwischen Clients und Servern, so dass sie Ressourcen und Hypermedien austauschen können.

Obwohl application/json und application/xml recht beliebte Medientypen sind, enthalten sie nicht viel Semantik. Sie beschreiben lediglich die im Dokument verwendete Gesamtsyntax. Es sollten speziellere Medientypen verwendet werden, die die HATEOAS-Anforderungen unterstützen (oder durch Medientypen von Anbietern erweitert werden ), z.

Ein Client teilt einem Server mit, welche Medientypen er kennt, indem er seiner Anfrage den Accept Header hinzufügt, zum Beispiel:

Accept: application/hal+json

Wenn der Server die angeforderte Ressource in einer solchen Darstellung nicht produzieren kann, gibt er 406 (NOT ACCEPTABLE) zurück . Andernfalls wird der Medientyp im Content-Type Header der Antwort hinzugefügt, die die dargestellte Ressource enthält. Beispiel:

Content-Type: application/hal+json

Staatenlos> stateful

Warum?

Ein Stateful-Server bedeutet, dass die Clientsitzungen in einem lokalen Speicher mit Serverinstanz gespeichert werden (fast immer in Webserversitzungen). Wenn Sie versuchen, horizontal zu skalieren , wird dies zu einem Problem: Wenn Sie mehrere Serverinstanzen hinter einem Load Balancer ausblenden, wird ein Client beim Anmelden zuerst an Instanz Nr. 1 gesendet, beim Abrufen einer geschützten Ressource anschließend an Instanz Nr. 2 Dann wird die zweite Instanz die Anfrage als anonyme behandeln, da die Clientsitzung lokal in Instanz # 1 gespeichert wurde .

Es wurde gefunden, dass Lösungen zur Lösung dieses Problems gefunden werden (z. B. durch Konfigurieren der Sitzungsreplikation und / oder ständigen Sitzung ). Die REST-Architektur schlägt jedoch einen anderen Ansatz vor: Machen Sie den Server nicht zustandslos, sondern stateless . Laut Fielding :

Jede Anfrage vom Client an den Server muss alle Informationen enthalten, die zum Verständnis der Anfrage erforderlich sind, und kann keinen auf dem Server gespeicherten Kontext nutzen. Der Sitzungsstatus wird daher vollständig auf dem Client gespeichert.

Mit anderen Worten, eine Anforderung muss auf dieselbe Weise behandelt werden, unabhängig davon, ob sie an die Instanz Nr. 1 oder die Instanz Nr. 2 gesendet wird . Aus diesem Grund werden zustandslose Anwendungen als einfacher skalierbar betrachtet .

Wie?

Ein gängiger Ansatz ist die tokenbasierte Authentifizierung , insbesondere bei den trendigen JSON-Webtokens . Beachten Sie, dass JWT immer noch einige Probleme hat, insbesondere in Bezug auf die Ungültigerklärung und die automatische Verlängerung des Ablaufs (z. B. die Funktion " Merken" ).

Seitennotizen

Die Verwendung von Cookies oder Headern (oder irgendetwas anderem) hat nichts damit zu tun, ob der Server zustandsbehaftet oder zustandslos ist: Dies sind nur Medien, die hier zum Transportieren von Token (Sitzungskennung für zustandsbehaftete Server, JWT usw.) verwendet werden, nichts weiter.

Wenn eine RESTful-API nur von Browsern verwendet wird, können Cookies ( HttpOnly and Secure ) sehr praktisch sein, da Browser sie automatisch an ausgehende Anforderungen anhängen. Wenn Sie sich für Cookies entscheiden, sollten Sie auf CSRF achten (eine gute Möglichkeit, dies zu verhindern, besteht darin, dass die Clients denselben eindeutigen geheimen Wert sowohl in einem Cookie als auch in einem benutzerdefinierten HTTP-Header generieren und senden ).


Cachefähige API mit bedingten Anforderungen

Mit dem Kopf der Last-Modified

Der Server kann für die Antworten, die Ressourcen enthalten, die im Cache gespeichert werden können, einen Datum-Header mit dem Datum der Last-Modified bereitstellen. Kunden sollten dieses Datum dann zusammen mit der Ressource speichern.

Jedes Mal, wenn Clients die API zum Lesen der Ressource anfordern, können sie jetzt einen If-Modified-Since Header hinzufügen, der das Last-Modified Datum der letzten Änderung enthält, das sie erhalten und gespeichert haben. Der Server muss dann den Header der Anforderung und das aktuelle Datum der letzten Änderung der Ressource vergleichen. Wenn sie gleich sind, gibt der Server eine 304 (NICHT MODIFIZIERT) mit leerem Rumpf zurück: Der anfragende Client sollte die aktuell zwischengespeicherte Ressource verwenden, über die er verfügt.

Wenn Clients die API zum Aktualisieren der Ressource anfordern (dh mit einem unsicheren Verb), können sie einen If-Unmodified-Since Header hinzufügen. Dies hilft beim Umgang mit Race-Bedingungen: Wenn der Header und das aktuelle Datum der letzten Änderung unterschiedlich sind, gibt der Server eine 412 (PRECONDITION FAILED) zurück . Der Client sollte dann den neuen Status der Ressource lesen, bevor er erneut versucht, die Ressource zu ändern.

Mit dem ETag Header

Ein ETag (Entity-Tag) ist eine Kennung für einen bestimmten Status einer Ressource. Dies kann ein MD5-Hash der Ressource für eine starke Validierung oder ein domänenspezifischer Bezeichner für eine schwache Validierung sein .

Im Grunde ist der Prozess derselbe wie beim Last-Modified Header: Der Server stellt einen ETag Header für die Antworten bereit, die Ressourcen enthalten, die im Cache gespeichert werden können, und die Clients sollten diesen Bezeichner dann zusammen mit der Ressource speichern.

Dann geben Clients einen If-None-Match Header an, wenn sie die Ressource mit dem neuesten ETag, den sie erhalten und gespeichert haben, lesen möchten. Der Server kann jetzt ein 304 (NOT MODIFIED) zurückgeben, wenn der Header mit dem tatsächlichen ETag der Ressource übereinstimmt.

Wiederum können Clients einen If-Match Header bereitstellen, wenn sie die Ressource ändern möchten, und der Server muss einen 412-Wert (PRECONDITION FAILED) zurückgeben, wenn der bereitgestellte ETag nicht mit dem tatsächlichen ETag übereinstimmt.

Zusätzliche Bemerkungen

ETag> Datum

Wenn Kunden in ihren Anforderungen sowohl Datum als auch ETag angeben, muss das Datum ignoriert werden. Ab RFC 7232 ( hier und hier ):

Ein Empfänger MUSS If-Modified-Since / If-Unmodified-Since ignorieren, wenn die Anforderung ein If-None-Match / If-Match Headerfeld enthält. Die Bedingung in If-None-Match / If-Match gilt als genauerer Ersatz für die Bedingung in If-Modified-Since / If-Unmodified-Since werden nur für die Interaktion mit älteren Intermediären kombiniert das kann If-None-Match / If-Match nicht implementieren.

Flache ETags

Obwohl es offensichtlich ist, dass die letzten Änderungsdaten zusammen mit den Ressourcen auf der Serverseite beibehalten werden, gibt es mit ETag mehrere Ansätze .

Ein üblicher Ansatz besteht darin, flache ETags zu implementieren: Der Server verarbeitet die Anforderung so, als ob keine bedingten Header gegeben wurden, generiert jedoch nur am Ende das ETag der Antwort, die er gerade zurückgibt (z. B. durch Hashing), und vergleicht es mit dem bereitgestellten. Dies ist relativ einfach zu implementieren, da nur ein HTTP-Interceptor benötigt wird (und je nach Server bereits viele Implementierungen vorhanden sind). Erwähnenswert ist jedoch, dass dieser Ansatz zwar Bandbreite einspart, nicht aber die Serverleistung :

Eine tiefere Implementierung des ETag-Mechanismus könnte potenziell viel größere Vorteile bieten - etwa das Beantworten einiger Anforderungen aus dem Cache und die Notwendigkeit, die Berechnung überhaupt durchzuführen -, aber die Implementierung wäre auf jeden Fall weder so einfach noch so steckbar wie der flache Ansatz hier beschrieben.


Häufige Fehler

Warum sollte ich keine Verben in URLs einfügen?

HTTP ist kein RPC : Was HTTP wesentlich von RPC unterscheidet, besteht darin, dass die Anforderungen an Ressourcen gerichtet sind . URL steht immerhin für Uniform Resource Locator, und eine URL ist eine URI : Uniform Resource Idenfitier. Die URL richtet sich an die Ressource, mit der Sie arbeiten möchten , die HTTP-Methode gibt an, was Sie damit tun möchten . HTTP-Methoden werden auch als Verben bezeichnet : Verben in URLs machen dann keinen Sinn. Beachten Sie, dass HATEOAS-Beziehungen auch keine Verben enthalten sollten, da Links auch auf Ressourcen abzielen.

Wie kann ich eine Ressource teilweise aktualisieren?

Wenn PUT Anforderungen Clients dazu auffordern, die gesamte Ressource mit den aktualisierten Werten zu senden, kann PUT /users/123 nicht verwendet werden, um beispielsweise die E-Mail eines Benutzers einfach zu aktualisieren. Wie von William Durand in Please erklärt. Patch nicht wie ein Idiot. Es stehen verschiedene REST-kompatible Lösungen zur Verfügung:

  • Machen Sie die Eigenschaften der Ressource verfügbar und verwenden Sie die PUT Methode zum Senden eines aktualisierten Werts, da die PUT Spezifikation angibt, dass teilweise Inhaltsaktualisierungen möglich sind, indem Sie auf eine separat identifizierte Ressource mit einem Status abzielen, der einen Teil der größeren Ressource überlappt :
PUT https://example.com/api/v1.2/users/123/email
body:
  new.email@example.com
  • Verwenden Sie eine PATCH Anforderung, die Anweisungen enthält, die beschreiben, wie die Ressource geändert werden muss (z. B. nach dem JSON-Patch ):
PATCH https://example.com/api/v1.2/users/123
body:
  [
    { "op": "replace", "path": "/email", "value": "new.email@example.com" }
  ]
PATCH https://example.com/api/v1.2/users/123
body:
  {
    "email": "new.email@example.com"
  }

Was ist mit Aktionen, die nicht in die Welt der CRUD-Operationen passen?

Zitat von Vinay Sahni in Best Practices für das Design einer pragmatischen RESTful-API :

Hier können die Dinge unscharf werden. Es gibt verschiedene Ansätze:

  1. Strukturieren Sie die Aktion so, dass sie wie ein Feld einer Ressource erscheint. Dies funktioniert, wenn für die Aktion keine Parameter verwendet werden. Beispielsweise könnte eine Aktivierungsaktion einem booleschen activated Feld zugeordnet und über einen PATCH an die Ressource aktualisiert werden.

  2. Behandle es wie eine Subressource mit RESTful-Prinzipien. Mit der API von GitHub können Sie beispielsweise einen Kern mit PUT /gists/:id/star und einen Stern mit DELETE /gists/:id/star .

  3. Manchmal haben Sie wirklich keine Möglichkeit, die Aktion einer vernünftigen REST-Struktur zuzuordnen. Beispielsweise ist eine Suche nach mehreren Ressourcen nicht wirklich sinnvoll, um auf den Endpunkt einer bestimmten Ressource angewendet zu werden. In diesem Fall wäre /search am sinnvollsten, obwohl es keine Ressource ist. Dies ist in Ordnung - tun Sie einfach das Richtige aus Sicht des API-Konsumenten und stellen Sie sicher, dass es eindeutig dokumentiert ist, um Verwirrung zu vermeiden.


Übliche Praktiken

  • API ist dokumentiert. Es stehen Tools zur Verfügung, die Sie beim Erstellen Ihrer Dokumentation unterstützen, z. B. Swagger oder Spring REST Docs .

  • Die API wird entweder über Header oder über die URL versioniert :

https://example.com/api/v1.2/blogs/123/articles
                        ^^^^
https://example.com/api/v1.2/blogs/123/articles
                             ^^^^^     ^^^^^^^^
  • URLs verwenden Kebab- Großbuchstaben (Wörter werden durch Leerzeichen getrennt und getrennt):
https://example.com/api/v1.2/quotation-requests
                             ^^^^^^^^^^^^^^^^^^
  • HATEOAS stellt eine "Selbst" -Link zu Ressourcen bereit, die auf sich selbst abzielen:
{
  ...,
  _links: {
    ...,
    self: { href: "https://example.com/api/v1.2/blogs/123/articles/789" }
    ^^^^
  }
}
  • HATEOAS-Beziehungen verwenden lowerCamelCase (die Wörter werden mit einem Kleinbuchstaben groß geschrieben, dann mit Ausnahme der ersten großgeschrieben und Leerzeichen weggelassen), damit JavaScript-Clients die Punktnotation verwenden können, wobei die JavaScript-Namenskonventionen beim Zugriff auf die Links beachtet werden:
{
  ...,
  _links: {
    ...,
    firstPage: { "href": "https://example.com/api/v1.2/blogs/123/articles?pageIndex=1&pageSize=25" }
    ^^^^^^^^^
  }
}

Blogs-Verwaltung über eine RESTful-HTTP-API

Die folgenden Beispiele verwenden HAL zum Ausdrücken von HATEOAS und verwenden Folgendes:

  • CURIE (Compact URI): Wird verwendet, um Links zur API-Dokumentation bereitzustellen
  • URI-Vorlagen : URI, der Parameter enthält, die ersetzt werden müssen, bevor der URI aufgelöst wird

Holen Sie sich Blog 123

Anfordern

GET https://example.com/api/v1.2/blogs/123
headers:
  Accept: application/hal+json

Antwort

status: 200 (OK)
headers:
  Content-Type: application/hal+json
body:
  {
    "id": 123,
    "title": "The blog title",
    "description": "The blog description",
    "_links": {
      "curies": [{ "name": "doc", "href": "https://example.com/docs/{rel}", "templated": true }],
      "self": { "href": "https://example.com/api/v1.2/blogs/123" },
      "doc:articles": { "href": "https://example.com/api/v1.2/blogs/123/articles{?pageIndex,pageSize}", "templated": true }
    }
  }

Erstellen Sie einen neuen Artikel in Blog 123

Anfordern

POST https://example.com/api/v1.2/blogs/123/articles
headers:
  Content-Type: application/json
  Accept: application/hal+json
  X-Access-Token: XYZ
body:
  {
    "title": "The title 2",
    "content": "The content 2"
  }

Antwort

status: 201 (CREATED)
headers:
  Content-Type: application/hal+json
body:
  {
    "id": 789,
    "title": "The title 2",
    "content": "The content 2",
    "_links": {
      "curies": [{ "name": "doc", "href": "https://example.com/docs/{rel}", "templated": true }],
      "self": { "href": "https://example.com/api/v1.2/blogs/123/articles/789" },
      "doc:blog": { "href": "https://example.com/api/v1.2/blogs/123", "title": "The blog title" },
      "doc:comments": { "href": "https://example.com/api/v1.2/blogs/123/articles/789/comments{?pageIndex,pageSize}", "templated": true }
    }
  }

Erhalten Sie Artikel 789 von Blog 123

Anfordern

GET https://example.com/api/v1.2/blogs/123/articles/789
headers:
  Accept: application/hal+json

Antwort

status: 200 (OK)
headers:
  Content-Type: application/hal+json
body:
  {
    "id": 789,
    "title": "The title 2",
    "content": "The content 2",
    "_links": {
      "curies": [{ "name": "doc", "href": "https://example.com/docs/{rel}", "templated": true }],
      "self": { "href": "https://example.com/api/v1.2/blogs/123/articles/789" },
      "doc:blog": { "href": "https://example.com/api/v1.2/blogs/123", "title": "The blog title" },
      "doc:comments": { "href": "https://example.com/api/v1.2/blogs/123/articles/789/comments{?pageIndex,pageSize}", "templated": true }
    }
  }

Holen Sie sich die vierte Seite von 25 Artikeln des Blogs 123

Anfordern

GET https://example.com/api/v1.2/blogs/123/articles?pageIndex=4&pageSize=25
headers:
  Accept: application/hal+json

Antwort

status: 200 (OK)
headers:
  Content-Type: application/hal+json
body:
  {
    "pageIndex": 4,
    "pageSize": 25,
    "totalPages": 26,
    "totalArticles": 648,
    "_link": {
      "firstPage": { "href": "https://example.com/api/v1.2/blogs/123/articles?pageIndex=1&pageSize=25" },
      "previousPage": { "href": "https://example.com/api/v1.2/blogs/123/articles?pageIndex=3&pageSize=25" },
      "self": { "href": "https://example.com/api/v1.2/blogs/123/articles?pageIndex=4&pageSize=25" },
      "nextPage": { "href": "https://example.com/api/v1.2/blogs/123/articles?pageIndex=5&pageSize=25" },
      "lastPage": { "href": "https://example.com/api/v1.2/blogs/123/articles?pageIndex=26&pageSize=25" }
    },
    "_embedded": [
      {
        ...
      }, {
        "id": 456,
        "title": "The title 1",
        "content": "The content 1",
        "_links": {
          "curies": [{ "name": "doc", "href": "https://example.com/docs/{rel}", "templated": true }],
          "self": { "href": "https://example.com/api/v1.2/blogs/123/articles/456" },
          "doc:blog": { "href": "https://example.com/api/v1.2/blogs/123", "title": "The blog title" },
          "doc:comments": { "href": "https://example.com/api/v1.2/blogs/123/articles/456/comments{?pageIndex,pageSize}", "templated": true }
        }
      }, {
        "id": 789,
        "title": "The title 2",
        "content": "The content 2",
        "_links": {
          "curies": [{ "name": "doc", "href": "https://example.com/docs/{rel}", "templated": true }],
          "self": { "href": "https://example.com/api/v1.2/blogs/123/articles/789" },
          "doc:blog": { "href": "https://example.com/api/v1.2/blogs/123", "title": "The blog title" },
          "doc:comments": { "href": "https://example.com/api/v1.2/blogs/123/articles/789/comments{?pageIndex,pageSize}", "templated": true }
        }
      }, {
        ...
      }
    ]
  }

Aktualisieren Sie Artikel 789 von Blog 123

Anfordern

PUT https://example.com/api/v1.2/blogs/123/articles/789
headers:
  Content-Type: application/json
  Accept: application/hal+json
  X-Access-Token: XYZ
body:
  {
    "id": 789,
    "title": "The title 2 updated",
    "content": "The content 2 updated"
  }

Antwort

status: 200 (OK)
headers:
  Content-Type: application/hal+json
body:
  {
    "id": 789,
    "title": "The title 2 updated",
    "content": "The content 2 updated",
    "_links": {
      "curies": [{ "name": "doc", "href": "https://example.com/docs/{rel}", "templated": true }],
      "self": { "href": "https://example.com/api/v1.2/blogs/123/articles/789" },
      "doc:blog": { "href": "https://example.com/api/v1.2/blogs/123", "title": "The blog title" },
      "doc:comments": { "href": "https://example.com/api/v1.2/blogs/123/articles/789/comments{?pageIndex,pageSize}", "templated": true }
    }
  }

Anmerkungen

  • Der Bezeichner, der zur Identifizierung der zu aktualisierenden Ressource verwendet wird, ist der in der URL : Der im Haupttext (falls vorhanden) muss ignoriert werden.
  • Wenn eine PUT Anforderung die gesamte Ressource aktualisiert, hätte der content der persistierten Ressource entfernt werden müssen, wenn kein content gesendet worden wäre.

Artikel 789 des Blogs 123 löschen

Anfordern

DELETE https://example.com/api/v1.2/blogs/123/articles/789
headers:
  Accept: application/hal+json
  X-Access-Token: XYZ

Antwort

status: 204 (NO CONTENT)
headers:
  Content-Type: application/hal+json
body:
  {
    "_links": {
      "curies": [{ "name": "doc", "href": "https://example.com/docs/{rel}", "templated": true }],
      "doc:blog": { "href": "https://example.com/api/v1.2/blogs/123", "title": "The blog title" }
    }
  }

Verstoß gegen REST

<stock>
    <add>
        <item>
            <name>Milk</name>
            <quantity>2</quantity>
        </item>
    </add>
</stock>

Wenn Sie diesen Körper einer Ressource wie /stocks/123 zuordnen, verstößt dies gegen die Idee hinter REST. Während dieser Rumpf put und alle erforderlichen Informationen enthält, enthält er auch einen Methodenaufruf, der irgendwo add wenn der Rumpf verarbeitet wird. Im Anschluss an REST würde man den item nach /stocks/123/items/ .



Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow