REST-APIs verstehen und nutzen
Published: 2023-12-12 22:38:21

# REST-APIs verstehen und nutzen

![](https://blog.disane.dev/content/images/2023/11/rest_api-standard-erklart_banner-1.jpeg)APIs: Allgegenwärtig und jeder nutzt sie , wenn auch in direkt. Aber wofür sind sie da und wie funktionieren sie? Wir klären auf 💡

---

Vielleicht hast du schon einmal gesehen oder gehört, dass moderne Anwendungen REST-APIs verwenden. API ist die Abkürzung für _**A**pplication **P**rogrammable **I**nterface_ und ermöglichen die Kommunikation zwischen (verteilten) System. REST steht für _**R**epresentational **S**tate **T**ransfer_. Im Klartext heißt das, dass alle Anfragen zustandlos sind. Für moderne Anwendungen bilden Sie also das Rückgrat der Kommunikation.

## Grundlagen

Moderne Anwendungen unterscheiden sich sehr von "alten" System, wo alles auf einem Server liegt. Weswegen der Austausch von Daten immer wichtiger wird. Zudem werden die Systeme immer weiter getrennt oder verteilt und müssen daher Schnittstellen (Interfaces) anbieten, über die eine genormte Kommunikation erfolgt. Genau dafür sind REST-APIs eingeführt worden. Wikipedia definiert eine REST-API wie folgt:

> Der Zweck von REST liegt schwerpunktmäßig auf der [Maschine-zu-Maschine-Kommunikation](https://de.wikipedia.org/wiki/Maschine-zu-Maschine-Kommunikation). REST stellt eine einfache Alternative zu ähnlichen Verfahren wie [SOAP](https://de.wikipedia.org/wiki/SOAP) und [WSDL](https://de.wikipedia.org/wiki/Web%5FServices%5FDescription%5FLanguage) und dem verwandten Verfahren [RPC](https://de.wikipedia.org/wiki/Remote%5FProcedure%5FCall) dar. Anders als bei vielen verwandten [Architekturen](https://de.wikipedia.org/wiki/Architektur%5F%28Informatik%29) kodiert REST keine Methodeninformation in den [URI](https://de.wikipedia.org/wiki/Uniform%5FResource%5FIdentifier), da der URI Ort und Namen der Ressource angibt, nicht aber die Funktionalität, die der Web-Dienst zu der Ressource anbietet. Der Vorteil von REST liegt darin, dass im WWW bereits ein Großteil der für REST nötigen Infrastruktur (z. B. Web- und Application-Server, [HTTP](https://de.wikipedia.org/wiki/Hypertext%5FTransfer%5FProtocol)\-fähige Clients, [HTML](https://de.wikipedia.org/wiki/Hypertext%5FMarkup%5FLanguage)\- und [XML](https://de.wikipedia.org/wiki/Extensible%5FMarkup%5FLanguage)\-Parser, Sicherheitsmechanismen) vorhanden ist und viele Web-Dienste per se REST-konform sind. Eine Ressource kann dabei über verschiedene [Medientypen](https://de.wikipedia.org/wiki/Internet%5FMedia%5FType) dargestellt werden, auch _Repräsentation der Ressource_ genannt.  
>  
> _Quelle:_ <https://de.wikipedia.org/wiki/Representational%5FState%5FTransfer>

Wir werden hierbei uns aber nur auf die Kommunikation über HTTP beschränken.

## Wie war es früher?

Früher (so bis ca. 2000/2005) war es teils so, dass (z.B. via PHP) die Daten direkt in das HTML auf dem Server projiziert worden sind und dann direkt mit den bereits gefüllten Daten an den Client ausgeliefert worden sind. Mobile Geräte oder Ähnliches gab es selten. Maschinen-zu-Maschinen-Kommunikation wurde z.B. Banken eher über SOAP, RPC oder WSDL (XML) durchgeführt.  
  
Hier war die Kommunikationsrichtung in der Regel nur unidirektional vom Server zum Client:

![](https://blog.disane.dev/content/images/2023/11/Unbenanntes-Diagramm.drawio--1-.png)

Ein Nachladen von Daten war auch nicht (oder nur selten) notwendig weswegen die Webseiten recht statisch waren.

## Wie ist es heute?

Mittlerweile sind aber nicht nur die Computer die einzigen die Daten konsumieren, sondern auch mobile Geräte (Handys, Autos, etc.) zudem gibt es nun auch Apps die auf Daten zugreifen müssen. Die Kommunikationen sind auch nicht mehr unidirektional sondern bidirektional, weil viele Daten auch nachgeladen werden (um [First Contentful Paint](https://web.dev/articles/fcp?hl=de) zu verringern). Eine heutige Struktur würde (vereinfacht) wie folgt aussehen:

![](https://blog.disane.dev/content/images/2023/11/API-Diagram.drawio--4-.png)

Und hierbei kommt dann die REST-API ins Spiel. 

## Welche Daten werden damit übertragen?

Prinzipiell können die APIs alle Art von Daten anbieten, geläufig sind aber tatsächlich lediglich textuelle Daten und Dateien.

Mit textuellen Daten meine ich jetzt nicht ein Buch oder etwas anderes. Nein. Hier meine ich strukturierte Daten. Für den Austausch von Daten hat sich der JSON-Standard mittlerweile (zum Glück 😑) sehr gut etabliert. Er definiert wie die Daten auszusehen haben, damit sie alle Systeme verstehen und auswerten können. Auch können APIs Dateien wie Bildern oder anderen Formaten bereitstellen.

## Wie sind APIs aufgebaut?

REST-APIs sind nach gewissen Schemata aufgebaut, wodurch sie sich einfach adressieren lassen.   
  
Im Wesentlichen bieten APIs gewisse Schlüsselworte, womit man definiert, was man machen möchte. Diese basieren auf auf dem [HTTP-Standard-Methoden](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods). Hier gibt es fünf Stück, die im täglichen Einsatz oft verwendet werden `GET`, `POST`, `PATCH`, `PUT` und `DELETE`. Damit lassen sich alle [CRUD-Aktionen](https://de.wikipedia.org/wiki/CRUD) abbilden.  
  
Um das zu veranschaulichen, schauen wir uns einmal die [PokéAPI](https://pokeapi.co/) an. Hiermit lassen sich Pokémon von dem Dienst abfragen. 

Grundlegend kann man sagen, dass APIs immer wie folgt aufgebaut sind:

```bash
https://server.com/[eventuelle Version]/{ressource}/{id}
```

Eine Ressource ist immer eine Entität, z.B. ein Pokémon, Auto, Artikel oder Benutzer.

Eventuelle Abweichungen können durch den API-Anbieter vorhanden sein. Daher prüfe bitte immer vorab die Doku deines Anbieters.

### Daten über eine API anfordern

Wir möchten nun Daten über ein gewisses Pokémon haben. Ich mag Mew eigentlich ziemlich gerne und möchte nun ein paar Daten für Mew haben. Alle (guten) API-Anbieter dokumentieren ihre API und zeigen, wie du sie nutzen kannst, teils auch mit Beispielen. So auch die PokéAPI:

[Documentation - PokéAPI![](https://pokeapi.co/pokeapi_192_square.png)PokéAPI![](https://pokeapi.co/static/pokeapi_256.3fa72200.png)](https://pokeapi.co/docs/v2)

Hierfür bietet sich die Methode `GET`an, mit der wir den Server anweisen uns Daten zu geben.

In der Dokumentation der PokéAPI finden wir hierzu auch einen Ressourcen-Endpunkt:

```bash
HTTP GET https://pokeapi.co/api/v2/pokemon/{id or name}/
```

Heißt, dass wir mit dem Endpunkt ein bestimmtes Pokémon mit einer `ID` oder einem `Namen` abfragen können.  
  
Normale Anfragen via `GET` können auch im Browser ausgeführt werden, da ein Abfragen einer normalen Webseite auch über ein `GET`geschieht.  
  
Geben wir nun also die obere URL für Pickachu ein, bekommen wir folgende Rückgabe:

![](https://blog.disane.dev/content/images/2023/11/image-53.png)

Generell lassen sich damit auch alle Pokémon abfragen, in dem man den Parameter `ID`oder `Name`einfach weg lässt (<https://pokeapi.co/api/v2/pokemon>):

![](https://blog.disane.dev/content/images/2023/11/image-54.png)

Hier gibt es nun eine kleine Spezialität, die aber in der Regel alle APIs haben, nämlich ein Paging. 

## Seitenweises Abrufen von Daten

Werden viele Daten auf einmal benötigt, setzt das natürlich den Server des API-Anbieters unter Last, die auch sehr vielen Datensätzen, sehr groß werden kann. Um genau dem entgegen zu wirken, arbeiten APIs häufig mit Pagings. Also dem Seitenweisem Zurückliefern von Daten. 

💡

Ob und in wie weit dein API-Anbieter Paging unterstützt, erfährst du in der Regel in der Dokumentation der API.

In dem oberen Beispiel aller Pokémons sehen wir also, dass es insgesamt 1292 Pokémons geben würde. Das wäre auch viel zu viel für eine Anfrage. Darum beinhalten viele APIs (die ich bisher kennengelernt habe) auch entsprechende Befehle zum Durchlaufen der Seiten. Meistens geschieht dies über den [Query-String](https://de.wikipedia.org/wiki/Query-String), dem man dann Parameter zur Seite und zur Anzahl der Ergebnisse übergeben kann. Zusätzlich werden in der Regel auch die nächste Seite und die vorherige Seite als Link zurück geliefert, damit der Entwickler die aktuelle, vorherige und nachfolgende Seite nicht manuell "berechnen" muss im Code. 

Eine Seite der PokéAPI für Pokémons kann man mit der nachfolgenden URL abrufen:

```bash
GET https://pokeapi.co/api/v2/pokemon?offset=20&limit=20
```

Hier gibt es den `offset` als Parameter (der Anfangspunkt der Seite) und ein Limit (für die Anzahl der liefernden Daten). Und so könnte man nun durch alle Seiten durchlaufen.

## Und wenn ich Daten verändert oder löschen muss?

Hierbei kommt es auch wieder sehr auf deinen Anbieter der API an, ob er solche Aktionen unterstützt. Auch das kannst du in der Doku erlesen.

Die PokéAPI bietet keine Endpunkte zum Ändern der Daten an, was aber auch völlig klar ist, weil es ja eine lesende Datenbank ist. Möchtest du aber nun tatsächlich Daten schreiben, kommt es sehr stark darauf an, was genau du tun möchtest. 

💡

Für die weiteren Schritte tun wir einfach so, als könne die PokéAPI auch Daten verändern. Das soll auch nur das Prinzip widerspiegeln, wie es grundlegend funktionieren würde.

### Datensatz anlegen

Zum Anlegen von Daten wird die Methode `POST`verwendet. Diese legt per Definition einen neuen Datensatz zur Ressource an. Damit der `POST`klappt, muss man natürlich auch noch entsprechende Daten mitgeben. Das geschieht in der Regel über den `BODY`einer Anfrage.   
  
Im Vergleich zu einem `GET`besitzt der `POST`nämlich einen Anfragen-Body, der die zu verwendenden Daten enthält und mit an die API gesendet werden muss. Solche Anfragen können in der Regel nicht einfach über den Browser durchgeführt werden, sondern sollten durch `cURL`, `Postman` oder eine Programmiersprache deiner Wahl gemacht werden. Aber ein Aufruf zum Hinzufügen des Pokémon `Marfra` könnte so aussehen:

```bash
HTTP POST https://pokeapi.co/api/v2/pokemon
HTTP PATCH https://pokeapi.co/api/v2/pokemon/{id}

Content-Type: application/json
{
  "name": "Marfra"
  ...
}
```

Hier ist es wichtig zu beachten, dass man das Format für den Body angibt. Für JSON wäre dieses Format `application/json`.

Wenn alles geklappt hat, dann wäre nun ein neues Pokémon angelegt worden und du bekommst in der Regel eine ID oder einen Bezeichner zurück geliefert, mit der du weitere Anfragen machen könntest. Falls nicht, bekommst du aber in der Rückgabe der Anfrage irgendein Hinweis darauf, warum es nicht geklappt hat.

### Datensatz verändern

Hier verhält es sich ähnlich wie mit dem Anlegen, nur, dass wir auch noch angeben müssen, welches Pokémon wir verändern wollen. Die verwendete Methode wäre in dem Falle `PATCH`. Wichtig ist, dass wir auch definieren müssen, welches Pokémon wir editieren möchten. Das geschieht in der Regel durch eine ID, Namen oder einem anderen eindeutigen Bezeichner.  
  
Möchten wir nun unser Pokèmon um die Ability `Super-Nerd` anreichern, könnte unsere Anfrage wie folgt aussehen:

```bash
HTTP PATCH https://pokeapi.co/api/v2/pokemon/{id}

Content-Type: application/json
{
  "ability": "Super-Nerd"
}
```

Wenn alles geklappt hat, dann wäre nun das bestehende Pokémon `Marfra`verändert worden. Falls nicht, bekommst du aber in der Rückgabe der Anfrage irgendein Hinweis darauf, warum es nicht geklappt hat.

Zur Änderung müssen nicht alle Daten vorliegen, hier reicht es aus, wenn der Body der Anfrage das zu ändernde Feld beinhaltet. Auch hier kann es Abweichungen geben, die der API-Anbieter festgelegt hat.

### Datensatz löschen

Hierzu können wir die Methode `DELETE`verwenden. Im Gegensatz zu einem `POST`oder `PATCH`besitzt diese Methode keinen Body. Brauchen wir auch nicht, weil wir die Ressource über den eindeutigen Bezeichner identifizieren müssen. Hier kommt wieder unsere `ID`ins Spiel. Unser `Marfra`\-Pokémon könnten wir mit dem Befehl löschen:

```bash
HTTP DELETE https://pokeapi.co/api/v2/pokemon/{id}
```

### Sonderfall `PUT`

Es gibt streng genommen noch einen weiteren Fall, nämlich `PUT`. Er kennzeichnet sich dadurch, dass er per Definition dafür geeignet ist, einen Datensatz mit allen Daten zu updaten bzw. zu ersetzen. Manchmal wir diese Methode auch als "Upsert" verwendet, der den Datensatz verändert, sofern es ihn gibt, alternativ anlegt. Das kommt aber sehr stark auf den API-Anbieter an.

Für `PUT`muss immer das gesamte zu ändernde Objekt (mit den Änderungen) übermittelt werden.

```bash
HTTP PUT https://pokeapi.co/api/v2/pokemon/{id}

Content-Type: application/json
{
  "name": "Marfra"
  "ability": "Super-Nerd"
}
```

## Status-Codes prüfen

Wenn deine API alles richtig gemacht hat oder aber etwas schiefläuft, dann wird sie dir das auch (mehr oder weniger genau) sagen. Hier ist es wichtig auf die [Status-Codes](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status) zu schauen, die aus dem HTTP-Standard entspringen.

Geläufige Status Codes wären:  
\- 200 = OK, Ressource gefunden und Methode ausgeführt  
\- 404 = Ressource nicht gefunden  
\- 5XX = Es gab einen Serverfehler

## Der JSON-Standard

Wie Ihr seht, ist es recht einfach Daten abzufragen und Daten an ein System zu geben. Kommen wir aber mal zum Standard, der mittlerweile für die Ablage, Abrufen und Übermitteln von Daten großflächig genutzt wird: [JSON](https://de.wikipedia.org/wiki/JavaScript%5FObject%5FNotation)

Nein, es hat nichts mit Jason Statham zutun, auch wenn das gerne als kleiner Running Gag verwendet wird.  

![](https://media0.giphy.com/media/l44QgV6RFRGgjDsDC/giphy.gif?cid=5a38a5a2ybjbjexytaoqyio5buggwboqccgb981tu177kdn1&ep=v1_gifs_search&rid=giphy.gif&ct=g)

JSON steht für _**J**ava**S**cript **O**bject **N**otation_ welches 1997 erstmalig von Douglas Crockfordt spezifiziert worden ist. Mittlerweile gibt es dazu auch einen RFC (Request for Comment) 8259 und eine ECMA-404.

Die Daten innerhalb eines JSON können beliebig tief geschachtelt werden und bestehenden Grundsätzlich aus folgenden Datentypen:

* Nullwert = NULL (leer)
* Boolescher Wert = true/false
* Zahlen = negative/positive, Dezimal- als auch Ganzzahlen oder mit Angabe von Exponenten (`e`bzw. `E`)
* Zeichenketten = "Ich bin eine Zeichenkette" (ggf. mit Escaping via `\`)
* Array = Indizierte Listen beginnend mit `[`und endend mit `]`)  
z.B. `[1, 2, 3, 4, 5]`
* Objekt = Komma geteilte, ungeordnete Listen von Eigenschaften  
z.B. `{ "name": "wert", "anzahl": 1, "werte": [ 1, 2, 3, 5, 4] }`

Alle Typen können mit einander vermischt und unendlich tief (theoretisch) verschachatelt werden. Im Gegensatz zu XML bietet es weitaus weniger Overhead.

Gerade im JavaScript-Bereich hat sich dieser Standard als "Goldstandard" entwickelt und wird auch zum Teil verwendet, um Dateien abzulegen, die viele Informationen enthalten und durch Programme/Anwendungen geschrieben und gelesen werden.

## Fazit

Du hast nun einen kleinen Einblick in die Welt von APIs, JSON und die vielfältigen Möglichkeiten bekommen, wie man APIs konsumiert und wie Systeme heutzutage mit einander plaudern. Viel Spaß beim "Anzapfen" von APIs und Nuten der Daten 🔥

💡

Speichere dir am besten diesen Artikel ab. Viele meiner weiteren Artikel basieren auf der Nutzung von APIs und/oder der Nutzung von JSON-Daten.

---

Und, hast du schon Ideen welche APIs du verwenden kannst oder hast du sogar schon eine eigene API? Lass es mich in den Kommentaren wissen 👇

---

If you like my posts, it would be nice if you follow my [Blog](https://blog.disane.dev) for more tech stuff.