JSON und REST-API

Ein REST-API (Representational State Transfer - Application Programming Interface) stellt Dienste zur Verfügung, um Daten und Funktionen zwischen Client und Server auszutauschen. Das sind die typischen Aufgaben von fetch im REST-API: Daten mit GET auslesen, mit POST Daten zum Server senden, mit PUT ändern und mit DELETE löschen.

JSON post, put, patch

JSON und REST-API

Das Abholen von Daten mit GET ist definitiv die am meist benutzte HTTP-Methode, aber GET ist immer eine lesende Methode. Wenn Daten nicht nur gelesen, sondern auch geändert, neue Daten erzeugt oder gelöscht werden, kommen die HTTP-Methoden POST, PUT, PATCH und DELETE zum Einsatz. Beispiele sind das Anlegen von Benutzerdaten mit POST, während PUT individuelle Datensätze aktualisiert oder teilweise ersetzt. PATCH aktualisiert nur einen Teil eines Datensatzes, meist um den Datentransfer im Vergleich gegenüber einem PUT zu reduzieren.

GETlesender Zugriff auf Daten
POSTAnlegen von Daten
PUTVollständiges Überschreiben vorhandener Daten
PATCHTeilweises Überschreiben vorhandener Daten
DELETELöschen von Datensätzen

Anders als beim Lesen von JSON-Daten braucht fetch() bei POST, PUT, PATCH die URL der Anwendung und die Optionen headers und body. Ein POST-Request kann eine body-Option haben, die einen String (hier JSON stringify) aufnimmt.

fetch(url, {
	method: "POST", // bzw. "PUT", "DELETE" oder "PATCH"
	headers: {
		'Content-Type': 'application/json'
	},
	body: JSON.stringify({
		firstname: document.querySelector("#firstname").value,
		lastname: document.querySelector("#lastname").value
	});
})

Mit dem fetch-API holt eine Anwendung Daten von einem Server über ein RESTful API. Das asynchrone fetch-API nutzt Promises, so dass die Anwendung entweder auf Antworten wartet (async await) oder Promise Chaining nutzt. fetch () übergibt einen RESTful-Endpoint (eine URL) als erstes Argument. Das zweite Argument ist ein Objekt (wird bei einem GET-Request nicht benötigt) mit drei Schlüsseln:

method
GET, POST, PUT, PATCH, DELETE
body
Informationen, die als Request gesendet werden (nicht bei GET-Request). Mit body muss auch immer der entsprechende Inhaltstyp {'Content-Type' : 'application/json'} angegeben werden.
headers
Metadaten zum Typ der Daten und i.d.R. API-Keys für die Authentifizierung.

DummyJSON – Üben und Erforschen

Auf DummyJSON gibt es REST-Endpoints mit JSON-Daten für die Entwicklung mit Javascript, jQuery, React, …, die als Platzhalter agieren. Schön für Fingerübungen.

Screenshot DummyJSON Homepage

DummyJSON stellt Testdaten für Themen wie Produkte, Benutzerdaten, Rezepte und Kommentare bereits. Das Projekt ist gut dokumentiert und kommt mit vielen Beispielen.

fetch: JSON-Datensätze ändern und speichern

Meistens wird JSON aus Datenquellen gelesen, in interaktiven Seiten aber auch geändert und als JSON an ein REST-API (z.B. eine PHP-Anwendung auf dem Server) zurückgegeben.

Anders als beim Lesen der JSON-Datei mit dem einfachen fetch ("data.json") braucht fetch() beim Senden von JSON die URL der Anwendung und die Optionen POST, headers und body.

Dieses spartanische Beispiel ändert Beiträge (Posts) von Benutzern und kann Taxonomie-Tags entfernen.

EditDeleteTitel

Response




Schon ein kleines, nur groß angerissenes Projekt wie dieses Beispiel bringt einen komplexen Ablauf, denn wir müssen immer wieder auf die Response warten. Dabei ist das Erstellen eines neuen Posts im Beispiel nicht einmal enthalten, die Eingaben werden nicht geprüft, Benutzer-Auth ist nicht implementiert.

  • Abholen der Datensätze mit fetch,
  • dann Platzieren der Daten im DOM,
  • dann Beobachten der Benutzeraktionen,
  • dann Reagieren auf Edit oder Delete,
  • dann – erst wenn Edit aktiv ist – den Editor mit Daten füllen,
  • optional: dann kann ein Tag gelöscht werden (neue Tags ist nicht implementiert),
  • dann kann ein Post geändert und versendet werden.

Beim Abholen muss GET nicht angegeben werden. Das Beispiel liest die Posts des Users mit der userId 5. listPosts (elem) erstellt die Liste der Datensätze für User 5 sowie die den Edit- und Delete-Buttons.

function postEditor () {

                        Endpunkt
           ┌───────────────┴────────────────┐
           │                                │
           ▼                                ▼
	fetch('https://dummyjson.com/posts/user/5')
	.then(res => res.json())
	.then(res => {
		// Platzieren der Daten im DOM
		res.posts.forEach (elem => listPosts (elem));
		return res.posts;
	})
Ein eventListener für Klicks auf Edit / Delete. editor(obj) schreibt die Werte in die Felder des Editors, deletePost(entry) löscht den Datensatz.

	.then (posts => {
		// Datensatz editieren
		edit.forEach ( btn => {
			btn.addEventListener ("click", function () {
				const obj = posts.find ((elem) => elem.id === Number(id));		
				editor (obj);
			})
		});
		
		// Datensatz löschen
		del.forEach ( btn => {
			btn.addEventListener ("click", function () {
				const entry = posts.find ((elem) => elem.id === Number(id));
				deletePost (entry);
			});
		});

	})

Ein POST- / PUT-Request kann eine body-Option haben, die einen String (hier JSON stringify) aufnimmt. Mit body muss auch immer der entsprechende Inhaltstyp {'Content-Type' : 'application/json'} angegeben werden.

Für ein Update des Datensatz braucht fetch die Optionen PUT, headers und body. Die Daten gehen in body.

function updatePost (id) {
	fetch(`https://dummyjson.com/posts/${id}`, {
	  method: 'PUT', /* or PATCH */
	  headers: { 'Content-Type': 'application/json' },
	  body: JSON.stringify({
		"title": document.querySelector ("#title").value,
		"body": document.querySelector ("#content").value,
		"tags": tags
	  })
	})
	.then(res => res.json())
	.then(console.log);
}

Natürlich speichert DummyJSON Änderungen nicht wirklich. Statt dessen dienen der Rückgabewert und die Response vom Server (Konsole > Netzwerk > Headers) als Bestätigung.

Suchen auf mediaevent.de