LU16 – HTTP, CRUD & Postman

Lernziele

Von SQL-CRUD zu Web-CRUD

Bisher im Modul M290:

Jetzt übertragen wir diese Idee auf das Web: Statt direkt SQL zu tippen, schicken wir HTTP-Anfragen an einen Backend-Server2) – bei uns: Express (Node.js). Der Server führt für uns die passenden CRUD-Operationen aus und sendet eine Antwort zurück.

Wir bauen zuerst eine API für Social-Media-Posts, noch ohne Datenbank – nur mit Daten in einem Javascript-Array. So können wir HTTP, Routen und Postman kennenlernen, bevor wir in in der nächsten Unterrichtseinheit MySQL an Express anbinden.

Schauen Sie sich das Video zum Unterricht an – Einführung in APIs und Umsetzung von CRUD mit express: Einführungs-Video API/CRUD

HTTP-Methoden – wie Bestellungen in einem Restaurant

Stellen Sie sich das so vor:

Jede HTTP-Anfrage hat unter anderem:

Der Server reagiert auf eine Anfrage, indem er:

  1. eine passende Route findet (z.B. app.get('/api/posts', …)),
  2. etwas ausführt (z.B. Daten lesen oder speichern),
  3. genau eine Antwort zurückschickt (z.B. JSON oder Text).

Route und Endpoint

Route (Express)

Eine Route ist die Server-Funktion im Code, die beschreibt, was bei einer bestimmten Kombination passiert:

(req, res) => {
    res.send('Hello World!');
}

Das hier ist die Handler-Funktion. req steht für Request (beinhaltet Anfrage-Parameter) und res steht für Response (Antwort-Objekt).

Beispiel: app.get('/api/posts', …) ist eine Route.

Endpoint (API)

Ein API-Endpoint ist eine Route, die als Daten-Schnittstelle8) für Clients gedacht ist. Meistens liefert sie die Daten im JSON9) Format zurück.

Beispiel: GET /api/posts → liefert Post-Daten als JSON (API-Endpoint).

CRUD & HTTP-Methoden

CRUD-Operationen werden bei Web-APIs typischerweise folgenden HTTP-Methoden zugeordnet:

CRUD HTTP-Methode Typisches Beispiel einer Route
Create POST POST /api/posts → Neuer Post wird angelegt
Read GET GET /api/posts → Alle Posts anzeigen; GET /api/posts/5 → Post mit ID 5 anzeigen
Update PUT PUT /api/posts/5 → Post mit ID 5 aktualisieren
Delete DELETE DELETE /api/posts/5 → Post mit ID 5 löschen

Später werden Sie für Ihre eigenen Use Cases (Reisen, Filme, Bücher, …) genau solche Routen definieren, z.B. GET /api/trips, POST /api/books, usw.

Postman – unser „Frontend-Ersatz“

 Postman logo

Im Modul M290 programmieren wir kein eigenes Browser-Frontend. Stattdessen benutzen wir Postman als Client:

Postman können Sie hier downloaden → Postman downloaden

 Screenshot Postman-Benutzeroberfläche mit den HTTP-Requests GET/POST/PUT/DELETE. Screenshot Postman-Benutzeroberfläche mit den HTTP-Requests GET/POST/PUT/DELETE.

So können wir die API testen, als wäre schon ein fertiges Frontend vorhanden – nur viel einfacher und kontrollierter.

Beispiel-API: Social-Media-Posts

Wir verwenden als Beispiel eine vereinfachte post-Tabelle aus einer Social-Media-Datenbank:

Express-Server mit Endpoints erstellen

Wir erstellen einen Express-Server mit einer lokalen Liste von Posts (ohne Datenbank-Anbindung vorerst). Danach bauen wir die ersten Routen:

Wie in Projekten aus der Realität arbeiten wir hier mit api-Routen (/api/posts) – das ist eine Konvention. Wir könnten auch nur /posts schreiben.

1. Start: Express-API für Posts

Wir bauen auf dem bekannten Server-Setup aus LU15 auf.

import express from 'express';
 
const app = express();
const port = 3000;
 
// Middleware: "sitzt" zwischen Anfrage und Route und verarbeitet Daten.
// express.json() liest den Request-Body und macht daraus req.body (JSON).
app.use(express.json());
 
// "Test-Tabelle" lokal
let posts = [
{
  post_id: 1,
  user_id: 1,
  title: 'Morning Coffee',
  image_url: 'https://picsum.photos/800/450?random=1',
  description: 'Nothing beats starting the day with a warm cup of coffee.',
  likes: 10
},
{
  post_id: 2,
  user_id: 2,
  title: 'Sunset Vibes',
  image_url: 'https://picsum.photos/800/450?random=2',
  description: 'Caught this beautiful sunset today! Nature never disappoints.',
  likes: 12
}
];
 
// TEST-Route (UI/Info)
app.get('/', (req, res) => {
  res.send('API ist online');
});
 
app.listen(port, () => {
  console.log(`API läuft auf http://localhost:${port}`);
});

Wenn Sie diesen Server mit npm run dev starten (falls Nodemon → s. LU15 installiert, sonst node index.js), sollten Sie im Browser unter http://localhost:3000/ den Text „API ist online“ sehen.

2. READ – Alle Posts abfragen

Jetzt fügen wir eine Route hinzu, die alle Posts zurückliefert:

// READ – alle Posts
app.get('/api/posts', (req, res) => {
  res.status(200).json(posts);
});

Test mit Postman oder Browser

 Screenshot alle Posts abfragen.

3. READ – Einzelnen Post nach ID abfragen

Wir möchten einen einzelnen Post anhand der post_id abfragen.

// READ – einzelner Post nach ID
app.get('/api/posts/:id', (req, res) => {
  const id = Number(req.params.id);     // Pfad-Parameter (Route-Parameter) holen. :id kommt immer als String -> Number(...) macht eine Zahl daraus
  const post = posts.find(p => p.post_id === id);
 
if (!post) {
  return res.status(404).send('Post nicht gefunden');
}
 
res.status(200).json(post);
});

Test mit Postman

 Screenshot eines einzelnen Posts abfragen.

4. CREATE – Neuen Post anlegen

Nun soll ein neuer Post erstellt werden. Dazu schicken wir einen im Request einen „Body“ mit den notwendigen Daten mit (im JSON-Format).

app.post('/api/posts', (req, res) => {
//Daten aus dem Anfrage-Objekt (Request) holen und in Variablen speichern
const user_id = req.body.user_id;
const title = req.body.title;
const image_url = req.body.image_url;
const description = req.body.description;
 
// ganz einfache Validierung (Pflichtfelder) - ohne titel oder user_id (wer post erstellt hat) können wir keinen neuen Post erstellen.
if (!title || !user_id) {
    return res.status(400).send('Please enter a title and a user_id');
}
 
// neue post_id berechnen - das wird in Zukunft die Datenbank selbst machen.
// Letzte Post-ID aus dem Post-Array herausfinden:
const lastPostId = posts[posts.length - 1].post_id;
const newPostId = lastPostId + 1;
 
const newPost = {
    post_id: newPostId,
    user_id: user_id,
    title: title,
    image_url: image_url || '',
    description: description || '',
    likes: 0
};
 
//neuer Post wird in Post-Array (Liste mit Posts) gespeichert
posts.push(newPost);
 
//Rückmeldung an Client: neuer Post und Status-Code 201 (Created)
res.status(201).json(newPost);
 
 
});

Erklärung

Pflichtfelder: title und user_id müssen vorhanden sein → sonst 400 Bad Request.

Neue ID: Wir nehmen die post_id des letzten Elements im Array und zählen +1.

Antwort: 201 Created + das neu erstellte Post-Objekt als JSON.

Dieser Ansatz mit posts[posts.length - 1] funktioniert nur, wenn:

  • das Array mindestens 1 Element hat, und
  • die Posts im Array nach post_id sortiert sind (letzter Post hat die höchste ID).

In echten Projekten übernimmt das später die Datenbank (AUTO_INCREMENT).

Test mit Postman

 Screenshot: einen neuen Post hinzufügen.

  1. Methode: POST
  2. Tab BodyrawJSON auswählen
  3. Beispiel-Body:
{
  "user_id": 3,
  "title": "Mein erster echter Post",
  "image_url": "https://example.com/image3.jpg",
  "description": "Gerade mit Postman erstellt!"
}
  1. Send klicken
    • Erwartung:
      • Status 201 Created
      • JSON-Objekt mit neuer post_id (z.B. 3)
  2. Anschliessend GET /api/posts erneut ausführen → der neue Post sollte in der Liste sein.

Ausblick

Auf der nächsten Seite sind die HTTP-Methoden PUT und DELETE am gleichen Beispiel (Social-Media-Posts) ausgeführt. Sie werden diese auch für Ihr Projekt brauchen.

In der nächsten Unterrichtseinheit (LU17):

1)
HTTP = „Hypertext Transfer Protocol“: ein Regelwerk, wie Clients und Server Daten austauschen.
2)
Backend-Server = Programm, das Anfragen entgegennimmt und Antworten zurückschickt; oft mit Datenbank-Logik dahinter.
3)
Client = Programm, das eine Anfrage sendet.
4)
Server = Programm, das Anfragen empfängt und Antworten liefert.
5)
Pfad = der Teil der URL nach Domain/Port, z.B. /api/posts, /api/food/1
6)
Body = „Datenkörper“ der Anfrage, z.B. ein JSON-Objekt bei POST/PUT
7)
Handler = Funktion, die ausgeführt wird, wenn die Route passt.
8)
Schnittstelle = klar definierter „Zugang“: welche URL, welche Methode, welche Daten kommen rein/raus.
9)
JSON = Datenformat, das wie ein JavaScript-Objekt aussieht; wird häufig in APIs verwendet.
10)
Statuscode = Zahl, die beschreibt, ob die Anfrage erfolgreich war und warum/nicht.
11)
Header = Zusatzinfos zur Antwort, z.B. Inhaltstyp oder Caching.
12)
PK = Primary Key / Primärschlüssel: eindeutige ID.
13)
FK = Foreign Key / Fremdschlüssel: verweist auf eine ID in einer anderen Tabelle.