Lektion 1 von 9
HTTP verstehen: Anfrage, Antwort, Statuscode
Du zerlegst HTTP-Anfragen und -Antworten in ihre Teile, deutest die wichtigsten Statuscodes und liest und schreibst JSON sicher.
Worum es geht
Bei der Frischvomhof AG in Sursee bestellen Kundinnen Eier, Bergkäse und Rüebli heute per Anruf oder WhatsApp direkt bei den Höfen. Die Bäuerin auf Hof Wyss in Buttisholz notiert alles auf einen Zettel, und am Samstag fehlen trotzdem zwei Bestellungen. Darum soll es eine Plattform geben: Höfe pflegen ihre Produkte, Kundschaft bestellt zur Abholung. Ein App-Team baut die App. Gian, Lernender im 2. Lehrjahr, baut das Backend: den Teil, den niemand sieht, auf den sich aber alle verlassen.
Bevor Gian eine Zeile Code schreibt, muss er die Sprache verstehen, in der App und Backend miteinander reden: HTTP. Wer Anfrage und Antwort lesen kann, sieht sofort, ob ein Fehler in der App liegt (falsche Anfrage) oder im Backend (falsche Antwort).
In dieser Lektion zerlegst du Anfragen und Antworten in ihre Teile, deutest die wichtigsten Statuscodes und liest und schreibst JSON. Im Code-Labor zerlegst du am Schluss eine rohe HTTP-Anfrage selbst.
Frontend, Backend, Datenbank: wer macht was?
Stell dir ein Restaurant vor. Du bestellst bei der Servicefachkraft, die Küche kocht mit Zutaten aus dem Lager, und die Servicefachkraft bringt dir den Teller. Küche und Lager siehst du nie, du hältst dich an die Speisekarte.
| Restaurant | Software |
|---|---|
| Gast am Tisch | Frontend: App oder Website |
| Speisekarte | API-Dokumentation: was man bestellen kann und wie |
| Servicefachkraft, die Bestellungen aufnimmt | API: die Schnittstelle des Backends |
| Küche | Backend: Geschäftslogik, Regeln, Berechnungen |
| Lager | Datenbank |
Zwei Dinge folgen daraus, und sie begleiten dich durch das ganze Modul:
- Nur das Backend redet mit der Datenbank. Die App bekommt nie ein Datenbank-Passwort, sonst könnte jede Person, die die App untersucht, direkt in die Tabellen schreiben.
- Das Backend vertraut dem Client nie. Jede Anfrage kann auch von einem Skript oder aus Postman kommen. Regeln setzt das Backend durch.
Eine API (Application Programming Interface) ist die Schnittstelle, über die Programme miteinander reden. Eine REST-API ist eine API, die Ressourcen wie Produkte oder Bestellungen über URLs anspricht und mit HTTP-Methoden bearbeitet. Eine Kombination aus Methode und URL wie GET /produkte/7 heisst Endpunkt.
Die Anfrage: Methode, URL, Header, Body
HTTP ist Text. So sieht eine Anfrage der App aus, wenn eine Kundin sechs Packungen Eier bestellt:
POST /bestellungen?quelle=app HTTP/1.1
Host: api.frischvomhof.ch
Content-Type: application/json
Accept: application/json
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOjV9.c2lnbmF0dXI
{"produktId": 7, "menge": 6, "abholdatum": "2026-10-17"}| Teil | Beispiel | Bedeutung |
|---|---|---|
| Methode | POST | was getan werden soll: lesen, anlegen, ändern, löschen |
| Pfad | /bestellungen | welche Ressource gemeint ist |
| Query | ?quelle=app | Zusatzangaben wie Filter, nach ?, mehrere mit & getrennt |
| Header | Content-Type: application/json | Metadaten: Format, Sprache, Anmeldung |
| Leerzeile | trennt die Header vom Body | |
| Body | {"produktId": 7, ...} | die eigentlichen Daten, meist JSON |
Die wichtigsten Methoden lernst du in Lektion 2 genau kennen. Für den Anfang reicht: GET liest, POST legt an, PUT ersetzt, PATCH ändert teilweise, DELETE löscht. Eine GET-Anfrage hat normalerweise keinen Body. Was sie braucht, steht im Pfad und in der Query.
Auch eine vollständige URL wie https://api.frischvomhof.ch:443/produkte?kategorie=Eier&hofId=3 besteht aus Schema (https), Host, Port (443), Pfad und Query.
Vier Header begegnen dir ständig:
- Content-Type: In welchem Format ist der Body, den ich mitschicke? Für JSON:
application/json. - Accept: In welchem Format möchte ich die Antwort?
- Authorization: Wer bin ich? Meist
Bearerund ein Token (Lektion 8). - Host: An welchen Server geht die Anfrage?
Header-Namen sind nicht von Gross- und Kleinschreibung abhängig: content-type und Content-Type sind derselbe Header.
Die App schickt folgende Anfrage:
PATCH /produkte/7?hofId=3 HTTP/1.1
Host: api.frischvomhof.ch
Content-Type: application/json
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxNCJ9.c2ln
{"preisRappen": 1100}Welche Aussage beschreibt die Teile der Anfrage korrekt?
Die Antwort: Statuscode, Header, Body
Das Backend antwortet ebenfalls mit Text:
HTTP/1.1 201 Created
Content-Type: application/json
Location: /bestellungen/1042
{"id": 1042, "status": "OFFEN", "totalRappen": 6300, "abholdatum": "2026-10-17"}Die erste Zeile enthält den Statuscode: eine dreistellige Zahl, die einem Programm sofort sagt, wie es gelaufen ist, ohne dass es Text lesen muss. Der Header Location zeigt, unter welcher URL die neue Bestellung abrufbar ist.
Die erste Ziffer verrät die Familie:
| Familie | Bedeutung | Wer muss handeln? |
|---|---|---|
| 1xx | Information, Zwischenmeldung | selten sichtbar |
| 2xx | Erfolg | niemand |
| 3xx | Umleitung, anderswo nachschauen | der Client folgt der neuen Adresse |
| 4xx | Fehler des Clients | der Client muss die Anfrage ändern |
| 5xx | Fehler des Servers | das Backend-Team |
Diese neun Codes brauchst du in diesem Modul immer wieder:
| Code | Name | Typische Situation bei Frischvomhof |
|---|---|---|
| 200 | OK | Produktliste erfolgreich gelesen |
| 201 | Created | Bestellung angelegt, mit Location-Header |
| 204 | No Content | Bestellung gelöscht, kein Body |
| 400 | Bad Request | Menge ist -3 oder das JSON ist kaputt |
| 401 | Unauthorized | kein oder ungültiges Token |
| 403 | Forbidden | angemeldet, aber fremder Hof |
| 404 | Not Found | Produkt 999 gibt es nicht |
| 409 | Conflict | Produkt ist ausverkauft |
| 500 | Internal Server Error | unerwarteter Fehler im Backend |
JSON in fünf Minuten
JSON (JavaScript Object Notation) ist das Format, in dem fast alle REST-APIs Daten austauschen:
{
"id": 7,
"name": "Freilandeier 10 Stk.",
"preisRappen": 1050,
"bio": false,
"beschreibung": null,
"kategorien": ["Eier", "Frisch"],
"hof": { "id": 3, "name": "Hof Wyss", "ort": "Buttisholz" }
}Die Regeln sind streng: Schlüssel und Texte stehen in doppelten Anführungszeichen. Zahlen, true, false und null stehen ohne Anführungszeichen. Nach dem letzten Element folgt kein Komma, und Kommentare gibt es nicht. "menge": "6" ist ein Text und keine Zahl. Ein sauberes Backend weist das zurück.
Ordne jeder Situation bei Frischvomhof den passenden Statuscode zu.
Zustandslos: Jede Anfrage steht für sich
HTTP ist zustandslos. Der Server erinnert sich zwischen zwei Anfragen an nichts, jede Anfrage bringt alles mit, was er braucht. Darum steht das Token in jeder Anfrage im Authorization-Header, nicht nur beim Login.
Der Vorteil: Weil keine Anfrage von einer vorherigen abhängt, kann später jeder von mehreren Backend-Servern jede Anfrage beantworten.
Welche Aussagen über HTTP und JSON sind korrekt? (Mehrere Antworten)
Wähle alle zutreffenden Antworten.
Schritt für Schritt: Vier Antworten der Bestell-API lesen
Gians erster Prototyp läuft lokal unter http://localhost:3000. Er schickt vier Anfragen mit curl -i (-i zeigt auch Statuszeile und Header) und liest jede Antwort wie die App.
Schritt 1: Produkte eines Hofs lesen.
curl -i "http://localhost:3000/produkte?hofId=3"HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
[{"id":7,"name":"Freilandeier 10 Stk.","preisRappen":1050},
{"id":8,"name":"Alpkäse 300 g","preisRappen":1290}]Zwischenergebnis: 200, der Body ist ein Array. Eine leere Liste wäre [] und ebenfalls 200, nicht 404: Die Ressource existiert, sie hat nur keine Treffer.
Schritt 2: Ein Produkt anfragen, das es nicht gibt.
curl -i http://localhost:3000/produkte/999HTTP/1.1 404 Not Found
Content-Type: application/json; charset=utf-8
{"meldung":"Produkt 999 nicht gefunden"}Zwischenergebnis: 404, weil die angesprochene Ressource /produkte/999 nicht existiert. Die App zeigt «Produkt nicht mehr verfügbar».
Schritt 3: Eine Bestellung anlegen.
curl -i -X POST http://localhost:3000/bestellungen \
-H "Content-Type: application/json" \
-d '{"produktId": 7, "menge": 6, "abholdatum": "2026-10-17"}'HTTP/1.1 201 Created
Location: /bestellungen/1042
Content-Type: application/json; charset=utf-8
{"id":1042,"status":"OFFEN","totalRappen":6300}Zwischenergebnis: 201 und ein Location-Header. Der Total stimmt: 6 mal 1050 Rappen ergibt 6300 Rappen, also CHF 63.00.
Schritt 4: Eine ungültige Bestellung schicken.
curl -i -X POST http://localhost:3000/bestellungen \
-H "Content-Type: application/json" \
-d '{"produktId": 7, "menge": -3, "abholdatum": "2026-10-17"}'HTTP/1.1 400 Bad Request
Content-Type: application/json; charset=utf-8
{"meldung":"menge muss mindestens 1 sein"}Zwischenergebnis: 400, die Anfrage selbst ist falsch. Die App markiert das Mengenfeld.
Schritt 5: Zusammenfassen. Gian notiert, was die App bei jedem Code tun soll:
| Anfrage | Status | Reaktion der App |
|---|---|---|
| Produkte von Hof 3 | 200 | Liste anzeigen |
| Produkt 999 | 404 | «nicht mehr verfügbar» |
| gültige Bestellung | 201 | Bestätigung, zur neuen Bestellung wechseln |
| Menge -3 | 400 | Feld markieren, Meldung zeigen |
Jetzt bist du dran: Zerlege eine rohe HTTP-Anfrage selbst, wie es jedes Framework im Hintergrund tut.
Code-Labor: Eine HTTP-Anfrage zerlegen
Jedes Backend-Framework zerlegt eingehende Anfragen, bevor dein Code sie sieht. Express legt das Ergebnis in req.method, req.path, req.query, req.headers und req.body. Baue das in vereinfachter Form nach.
Schreibe zerlegeAnfrage(text). Sie liefert ein Objekt mit methode, pfad, query (Objekt, Werte dekodiert), header (Objekt, Namen in Kleinbuchstaben) und body (Text nach der Leerzeile, sonst "").
Achtung: Der Header Host: localhost:3000 enthält selbst einen Doppelpunkt.
Typische Fehler
- Für alles 200 zurückgeben. Steht der Fehler nur im Text, muss die App jede Antwort durchsuchen, und Monitoring-Werkzeuge sehen keine Fehler. Der Statuscode muss zur Situation passen.
- Content-Type vergessen. Schickt die App JSON ohne
Content-Type: application/json, liest das Backend den Body nicht, und alle Felder fehlen scheinbar. Prüfe bei rätselhaften 400ern zuerst die Header. - Zahlen als Text schicken.
"menge": "6"ist ein String. Je nach Backend wird er abgewiesen oder falsch weiterverarbeitet. Zahlen gehören ohne Anführungszeichen ins JSON. - Eine leere Liste mit 404 beantworten. Eine Suche ohne Treffer ist ein Erfolg mit leerem Ergebnis: 200 und
[].
Zusammenfassung
- Das Frontend stellt dar, das Backend setzt Regeln durch und spricht als Einziges mit der Datenbank.
- Eine Anfrage besteht aus Methode, Pfad mit Query, Headern, Leerzeile und optionalem Body.
- Eine Antwort besteht aus Statuscode, Headern und Body. 2xx ist Erfolg, 4xx ein Fehler der Anfrage, 5xx ein Fehler des Servers.
- JSON verlangt doppelte Anführungszeichen, Zahlen ohne Anführungszeichen und keine Kommentare. Beträge in Rappen, Datum nach ISO 8601.
- HTTP ist zustandslos: Jede Anfrage bringt alles mit, auch das Token.
- Mit
curl -i, Postman oder Bruno siehst du Status, Header und Body und erkennst, auf welcher Seite ein Fehler liegt.
Mit deiner eigenen KI vertiefen
Kopiere einen Prompt in Claude, ChatGPT oder Claude Code. Er macht die KI zur Lernbegleitung statt zum Lösungsautomaten.
HTTP verstehen mit Kontrollfragen Chat-KI
Die KI erklärt dir Anfrage, Antwort und Statuscodes an Beispielen und prüft danach, ob du es wirklich verstanden hast. Gut nach Lektion 1.