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:30] 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 29: Zeile 29:
 Wenn Sie mit Postman testen, sehen Sie immer einen Statuscode. Dieser Code ist Ihr „Kurzfazit“, ob der Request geklappt hat. Wenn Sie mit Postman testen, sehen Sie immer einen Statuscode. Dieser Code ist Ihr „Kurzfazit“, ob der Request geklappt hat.
  
-{{:modul:m290_guko:learningunits:lu17:theorie:http_statuscodes.png?direct&1100| HTTP-Statuscodes }}+{{ :modul:m290_guko:learningunits:lu17:theorie:http_statuscodes.png?direct&1100 | HTTP-Statuscodes }}
  
 <WRAP center box round 80%> <WRAP center box round 80%>
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.1766759446.txt.gz
  • Zuletzt geändert: 2025/12/26 15:30
  • von gkoch