Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen Revision Vorhergehende Überarbeitung
Nächste Überarbeitung
Vorhergehende Überarbeitung
modul:m290_guko:learningunits:lu17:theorie:a_intro [2025/12/26 15:31] gkochmodul:m290_guko:learningunits:lu17:theorie:a_intro [2026/01/12 07:43] (aktuell) gkoch
Zeile 3: Zeile 3:
 ===== Lernziele ===== ===== Lernziele =====
   * Sie können Ihre **MySQL-Datenbank** aus einem Express-Server heraus ansprechen.   * Sie können Ihre **MySQL-Datenbank** aus einem Express-Server heraus ansprechen.
-  * Sie können die CRUD-Routen aus LU16 (''GET'', ''POST'', ''PUT'', ''DELETE'') so erweitern, dass sie mit einer **echten Tabelle ''post''** arbeiten.+  * Sie können die CRUD-Routen aus LU16 (''GET'', ''POST'', ''PUT'', ''DELETE'') so erweitern, dass sie mit einer **echten Tabelle ''posts''** arbeiten.
   * Sie setzen einfache **Validierung** ein (Pflichtfelder prüfen).   * Sie setzen einfache **Validierung** ein (Pflichtfelder prüfen).
   * Sie verwenden passende **HTTP-Statuscodes** (200, 201, 400, 404, 500).   * Sie verwenden passende **HTTP-Statuscodes** (200, 201, 400, 404, 500).
Zeile 19: Zeile 19:
 In LU17 ersetzen Sie diese In-Memory-Liste durch eine echte Datenbank: In LU17 ersetzen Sie diese In-Memory-Liste durch eine echte Datenbank:
  
-  * Die Daten kommen aus der **MySQL-Tabelle ''post''**.+  * Die Daten kommen aus der **MySQL-Tabelle ''posts''**.
   * Ihr Express-Server ist die **Brücke** zwischen Client (Postman) und Datenbank.   * Ihr Express-Server ist die **Brücke** zwischen Client (Postman) und Datenbank.
   * Die gleiche Idee bleibt: **HTTP-Anfrage → Route → Logik/SQL → HTTP-Antwort**.   * Die gleiche Idee bleibt: **HTTP-Anfrage → Route → Logik/SQL → HTTP-Antwort**.
Zeile 42: Zeile 42:
 </WRAP> </WRAP>
  
-===== Vorbereitung: MySQL-Tabelle post ===== +===== Vorbereitung: MySQL-Datenbank "social_media" ===== 
-Eine mögliche Tabellenstruktur (vereinfacht):+Für die Verbindung mit MySQL benötigen wir eine bestehende Datenbank. Wir arbeiten mit der Datenbank "social_media", welche die Tabellen users und posts beinhaltet. 
 + 
 +<WRAP center round download 60%> 
 +Laden Sie hier den SQL-Dump herunter und lassen Sie das Skript in Webstorm laufen via //Run SQL Script...// (eine Anleitung, wie das prinzipiell geht finden Sie in LU09). 
 +{{ :modul:m290_guko:learningunits:lu17:theorie:social_media_db-dump.sql.zip |SQL-Dump einer fiktiven Social-Media-Datenbank}} 
 +</WRAP> 
 + 
 +Das ERD der Datenbank sieht so aus: 
 +{{ :modul:m290_guko:learningunits:lu17:theorie:social_media_crowsfoot_ids_updated.drawio.png?direct&900 | Crow's Foot Diagramm Social Media DB}} 
 + 
 +Eine mögliche Tabellenstruktur für die Tabelle "posts":
  
 <WRAP center box round 80%> <WRAP center box round 80%>
 ^ Spalte ^ Datentyp ^ Beschreibung ^ ^ Spalte ^ Datentyp ^ Beschreibung ^
-| ''post_id'' | INT, PRIMARY KEY, AUTO_INCREMENT | Primärschlüssel |+| ''id'' | INT, PRIMARY KEY, AUTO_INCREMENT | Primärschlüssel |
 | ''user_id'' | INT | Referenz auf User (FK) | | ''user_id'' | INT | Referenz auf User (FK) |
 | ''title'' | VARCHAR(255) | Titel des Posts | | ''title'' | VARCHAR(255) | Titel des Posts |
Zeile 55: Zeile 65:
 </WRAP> </WRAP>
  
-Diese Tabelle legen Sie mit einem SQL-DDL-Skript an (wie bisher im Modul)  +<WRAP center round important 60%> 
-Importieren Sie zusätzlich Startdaten (DML), damit Sie direkt testen können.+Achtung: Die Primär-Spalte heisst neu ''id'' und nicht mehr ''post_id'' wie in LU16
 +</WRAP>
  
 ===== Schritt 1: mysql2 installieren ===== ===== Schritt 1: mysql2 installieren =====
Zeile 185: Zeile 196:
   // SQL-Abfrage: alle Spalten, die wir zurückgeben möchten   // SQL-Abfrage: alle Spalten, die wir zurückgeben möchten
   const sql = `   const sql = `
-    SELECT post_id, user_id, title, image_url, description, likes +    SELECT id, user_id, title, image_url, description, likes 
-    FROM post+    FROM posts
   `;   `;
  
Zeile 205: Zeile 216:
 </WRAP> </WRAP>
  
-**Test in Postman**+=== Test in Postman ===
   * Methode: ''GET''   * Methode: ''GET''
   * URL: ''http://localhost:3000/api/posts''   * URL: ''http://localhost:3000/api/posts''
Zeile 228: Zeile 239:
  
   const sql = `   const sql = `
-    SELECT post_id, user_id, title, image_url, description, likes +    SELECT id, user_id, title, image_url, description, likes 
-    FROM post +    FROM posts 
-    WHERE post_id = ?+    WHERE id = ?
   `;   `;
  
Zeile 274: Zeile 285:
  
   const sql = `   const sql = `
-    INSERT INTO post (user_id, title, image_url, description, likes)+    INSERT INTO posts (user_id, title, image_url, description, likes)
     VALUES (?, ?, ?, ?, 0)     VALUES (?, ?, ?, ?, 0)
   `;   `;
Zeile 295: Zeile 306:
     // insertId kommt von MySQL AUTO_INCREMENT     // insertId kommt von MySQL AUTO_INCREMENT
     const newPost = {     const newPost = {
-      post_id: result.insertId, +      id: result.insertId, 
-      user_id, +      user_id: user_id, 
-      title,+      title: title,
       image_url: image_url || '',       image_url: image_url || '',
       description: description || '',       description: description || '',
Zeile 308: Zeile 319:
 </code> </code>
 </WRAP> </WRAP>
 +
 +=== Test in Postman ===
  
 **Test-Body (Postman → Body → raw → JSON)** **Test-Body (Postman → Body → raw → JSON)**
Zeile 323: Zeile 336:
  
 ==== UPDATE: Post ändern (PUT /api/posts/:id) ==== ==== UPDATE: Post ändern (PUT /api/posts/:id) ====
-Hier übernehmen Sie die Idee aus LU16 (Update– aber jetzt mit SQL ''UPDATE''.+ 
 +In LU16b haben Sie einen Post so aktualisiert: Der ganze Datensatz wird ersetzt, wenn wir ein Update machen. 
 +Genau diese Logik übernehmen wir jetzt – der Unterschied ist nur: statt im Array ändern wir jetzt die MySQL-Tabelle ''posts''. 
  
 <WRAP box round center 80%> <WRAP box round center 80%>
 <code javascript> <code javascript>
 // UPDATE – Post vollständig ersetzen (PUT) // UPDATE – Post vollständig ersetzen (PUT)
 +// Route: PUT http://localhost:3000/api/posts/1
 app.put('/api/posts/:id', (req, res) => { app.put('/api/posts/:id', (req, res) => {
 +
   const id = Number(req.params.id);   const id = Number(req.params.id);
 +
   if (Number.isNaN(id)) {   if (Number.isNaN(id)) {
     return res.status(400).send('Ungültige ID (muss eine Zahl sein)');     return res.status(400).send('Ungültige ID (muss eine Zahl sein)');
   }   }
  
-  // Alle Felder werden erwartet+  // Alle Felder werden erwartet (PUT ersetzt alles)
   const user_id = req.body.user_id;   const user_id = req.body.user_id;
   const title = req.body.title;   const title = req.body.title;
Zeile 341: Zeile 360:
   const likes = req.body.likes;   const likes = req.body.likes;
  
-  // Validierung: alle Pflichtfelder vorhanden+  // Validierung: fehlen Felder? 
-  if (user_id === undefined || title === undefined || image_url === undefined || description === undefined || likes === undefined) {+  // likes kann 0 sein -> deshalb auf undefined prüfen 
 +  if ( 
 +    user_id === undefined || 
 +    title === undefined || 
 +    image_url === undefined || 
 +    description === undefined || 
 +    likes === undefined 
 +  ) {
     return res.status(400).send('Bitte user_id, title, image_url, description und likes mitsenden (PUT ersetzt alles).');     return res.status(400).send('Bitte user_id, title, image_url, description und likes mitsenden (PUT ersetzt alles).');
   }   }
  
-  const sql = UPDATE post SET user_id = ?, title = ?, image_url = ?, description = ?, likes = ? WHERE post_id = ? ;+  const sql = 
 +    UPDATE posts 
 +    SET user_id = ?, title = ?, image_url = ?, description = ?, likes = ? 
 +    WHERE id = ? 
 +  `;
  
   const values = [user_id, title, image_url, description, likes, id];   const values = [user_id, title, image_url, description, likes, id];
Zeile 360: Zeile 390:
     }     }
  
-    // Update hat geklappt: Status 200 + das "neue" Objekt zurückgeben+    // 200 OK + das "neue" Objekt zurückgeben
     res.status(200).json({     res.status(200).json({
-      post_id: id, +      id: id, 
-      user_id, +      user_id: user_id, 
-      title, +      title: title, 
-      image_url, +      image_url: image_url, 
-      description, +      description: description, 
-      likes+      likes: likes
     });     });
- 
   });   });
 }); });
Zeile 375: Zeile 404:
 </WRAP> </WRAP>
  
 +=== Test in Postman ===
  
-==== DELETEPost löschen (DELETE /api/posts/:id) ====+**Test-Body** 
 +<WRAP box round center 80%> 
 +<code json> 
 +
 +  "user_id"1, 
 +  "title": "Titel (replaced)", 
 +  "image_url": "https://example.com/new.jpg", 
 +  "description""Dieser Post wurde komplett ersetzt.", 
 +  "likes":
 +
 +</code> 
 +</WRAP>
  
 +Erwartung:
 +  * Status ''200 OK''
 +  * JSON-Objekt des aktualisierten Posts (inkl. neuem ''title'' und ''likes'')
 +
 +
 +==== DELETE: Post löschen (DELETE /api/posts/:id) ====
 <WRAP box round center 80%> <WRAP box round center 80%>
 <code javascript> <code javascript>
 // DELETE – Post löschen // DELETE – Post löschen
-// Route: DELETE http://localhost:3000/api/posts/1 
 app.delete('/api/posts/:id', (req, res) => { app.delete('/api/posts/:id', (req, res) => {
  
Zeile 390: Zeile 436:
   }   }
  
-  const sql = 'DELETE FROM post WHERE post_id = ?';+  const sql = 'DELETE FROM posts WHERE id = ?';
  
   db.query(sql, [id], (err, result) => {   db.query(sql, [id], (err, result) => {
- 
     if (err) {     if (err) {
       console.error('DB-Fehler bei DELETE /api/posts/:id:', err);       console.error('DB-Fehler bei DELETE /api/posts/:id:', err);
Zeile 403: Zeile 448:
     }     }
  
-    // Statuscode: 200 + Message +    // Antwort: 200 + Message 
-    res.status(200).json({ message: `Post mit post_id=${id} wurde gelöscht.` });+    res.status(200).json({ message: `Post mit id=${id} wurde gelöscht.` });
  
   });   });
Zeile 410: Zeile 455:
 </code> </code>
 </WRAP> </WRAP>
 +
 +=== Test mit Postman ===
 +
 +  * Methode: ''DELETE''
 +  * URL: ''http://localhost:3000/api/posts/1''
 +
 +Erwartung:
 +  * Status ''200 OK''
 +  * JSON-Objekt des gelöschten Posts
 +  * Danach ''GET /api/posts/1'' → ''404 Not Found''
  
  
Zeile 423: Zeile 478:
  
 ===== Transfer auf Ihr Projekt (LB03) ===== ===== Transfer auf Ihr Projekt (LB03) =====
-Für Ihr Projekt ersetzen Sie ''post'' durch Ihre eigenen Tabellen (z.B. ''serie'', ''actor'', ''serie_actor''):+Für Ihr Projekt ersetzen Sie ''posts'' durch Ihre eigenen Tabellen (z.B. ''serie'', ''actor'', ''serie_actor''):
  
   * Ressourcen-Route: z.B. ''/api/serien''   * Ressourcen-Route: z.B. ''/api/serien''
  • modul/m290_guko/learningunits/lu17/theorie/a_intro.1766759478.txt.gz
  • Zuletzt geändert: 2025/12/26 15:31
  • von gkoch