GraphQL. Dominik Kress
Чтение книги онлайн.
Читать онлайн книгу GraphQL - Dominik Kress страница 8
Abb. 1–2 Ressourcen, Repräsentation und URI im Zusammenhang
Kommunizieren kann der Client mit den Ressourcen bei einer RESTful API über HTTP und dessen Methoden. Diese sind POST, GET, PUT sowie DELETE und bilden die CRUD-Operationen (Create, Read, Update, Delete). Die Kommunikation findet dabei in einem Request/Response-Muster statt. Der Client stellt über die HTTP-Methoden entsprechende Requests an die gewünschte Ressource des API, und der Server antwortet mit einer Response: bei einem lesenden Zugriff beispielsweise mit der Repräsentation dieser Ressource im Body der Response.
Ein Request auf solch ein RESTful API über die Konsole – mit einem sogenannten cURL-Befehl – würde beispielhaft dann wie folgt aussehen:
$ curl -X GET "https://api.shop.com/user/5"
Listing 1–1 REST GET Request
Hier fordert der Client einen lesenden Zugriff auf den User mit der ID 5. Auf diesen Request würde er nun vom Server folgende Response erhalten:
< HTTP/1.1 200 OK
< Status: 200 OK
< Content-Length: 1782
< Content-Type: application/json
<
{"id":"5","username":"luke"}
Listing 1–2 REST GET Response
Der HTTP-Statuscode zeigt an, dass der Request erfolgreich abgearbeitet wurde. Die Rückgabe enthält mit dem JSON-Objekt am Ende die Repräsentation der Ressource des Users mit der id = 5. Ähnlich funktioniert auch ein schreibender Request des Clients:
$ curl -X PUT "https://api.shop.com/user/5" -d
'{"id":"5","username":"leia"}'
Listing 1–3 REST PUT
Bei diesem Beispiel handelt es sich um einen Request zum Überschreiben des Nutzers mit der id = 5. Die neue Objektrepräsentation wird im Request mitgeliefert und ersetzt serverseitig die bisherige Repräsentation der Ressource.
Ein weiterer Punkt in Fieldings Definition von REST – oder eher noch: sein Hauptaugenmerk bei der Architektur – war das sogenannte Hypermedia as the Engine of Application State oder auch HATEOS. Hierbei sollte der Zugriff des Clients lediglich auf einen initialen Endpunkt des Service beschränkt werden. Dieser hält neben der eigenen Repräsentation auch Verbindungen zu anderen Ressourcen bereit. Ein Client kann also alle möglichen Endpunkte dynamisch entdecken – ähnlich dem Durchklicken verschiedener Links auf einer Webseite.
HATEOS wird jedoch selten strikt durchgesetzt, weshalb nicht unbedingt Fieldings Vision von REST, sondern eher eine pragmatischere Interpretation heute als REST bezeichnet wird und weitläufig verbreitet ist.
1.4.3JSON:API
JSON:API ist eine JSON-basierte API-Spezifikation mit dem Ziel, API-Calls effizienter zu gestalten. Genau wie REST ist es eine Kombination aus HTTP und JSON sowie einer Definition von Regeln und Standards für die Kommunikation. JSON:API hat einfache Ressourcen, die über einen Call gegen den definierten Endpunkt des Service abgerufen werden können.
GET /articles HTTP/1.1
Accept: application/vnd.api+json
Listing 1–4 JSON API Get Request
Als Response liefert der Server ein JSON-Dokument. Das hat eine definierte, erwartbare Struktur. So hält es ein Relationship-Objekt, das sowohl Informationen über die Beziehung der Ressource zu anderen Ressourcen hält, als auch weitere, einfache Informationen zur Beziehung. Ruft man den Link innerhalb der angegebenen Relation auf, erhält man die Repräsentation der in Beziehung zu ihr stehenden Ressource – ähnlich dem HATEOS-Prinzip bei REST.
// ...
{
"type": "articles",
"id": "1",
"attributes": {
"title": "The Force for Beginners"
},
"relationships": {
"author": {
"links": {
"self": "http://example.com/articles/1/relationships/author",
"related": "http://example.com/articles/1/author"
},
"data": {
"type": "people",
"id": "9"
}}},
"links": {
"self": "http://example.com/articles/1"
}
} // ...
Listing 1–5 JSON API Get Response
Zusätzlich bietet JSON:API jedoch eine für das Verbinden verschiedener Ressourcen extrem nützliche Funktionalität: Compound Documents. Dabei handelt es sich um die Repräsentation einer Ressource, die eine in Relation stehende Ressource inkludiert.
Somit kann im oberen Beispiel die Repräsentation des Artikels durch die Informationen des verlinkten Autors erweitert werden; ohne dass man dabei den Roundtrip eines zweiten Requests auf einen verlinkten Endpunkt machen muss.
// ...
{
"data": [{
"type": "articles",
"id": "1",
"attributes": {
"title": "The Force for Beginners"
},
"links": {
"self": "http://example.com/articles/1"
},