diff --git a/web/09/09_aufgaben.md b/web/09/09_aufgaben.md new file mode 100644 index 0000000..2c07ac6 --- /dev/null +++ b/web/09/09_aufgaben.md @@ -0,0 +1,124 @@ +# Übungsblatt 09 + +### Hinweise: + +- Aufgabe 3 + 6: Keine Abgabe erforderlich +- **Aufgabe 1 + 2 + 4 + 5: Abgabe erforderlich** + +Im Normalfall ist **immer** eine Abgabe erforderlich, es sei denn es gibt einen expliziten Hinweis! + +## 1. Go-Übung: Datenbank INSERT + +**Aufgabenstellung**: Erstellen Sie ein Webserver-Programm in Go, dass beim Aufruf eines Endpunkts `/insert` einen neuen Datensatz in der Datenbank speichert. + +#### Hinweis +Siehe [Hinweise zu Aufgaben 2 und 3](#Hinweise-zu-Aufgaben-1-und-2) weiter unten. + +## 2. Go-Übung: Datenbank UPDATE + +**Aufgabenstellung**: Erweitern Sie das Programm aus Aufgabe 4 um einen neuen Endpunkt `/update`, der einen vorhandenen Datensatz in der Datenbank aktualisiert. + +#### Hinweis +Siehe [Hinweise zu Aufgaben 1 und 2](#Hinweise-zu-Aufgaben-1-und-2) weiter unten. + +### Hinweise zu Aufgaben 1 und 2 +1. Erstellen Sie zunächst die benötigten Tabellen und Datensätze in Ihrer Datenbank. Eine Anleitung hierfür finden Sie hier: [Datenbank vorbereiten](db/anleitung_db.md) +2. Verwenden Sie folgende Schnittstellen-Definition für Ihre Implementierung: [Swagger-API](hobbiesapi.json) +3. Tipp: Um die Elemente eines Slice in einem String zusammenzufügen, können Sie das Paket `strings` aus der Standard-Bibliothek verwenden: [strings.Join](https://pkg.go.dev/strings#Join) + +## 3. Dev-Container aktualisieren + +_Keine Abgabe erforderlich_ + +**Aufgabenstellung**: Aktualisieren Sie Ihren Dev-Dontainer in VS Code als Vorbereitung auf die nächste Vorlesung und Labor. + +#### Arbeitsschritte + +1. Neueste Änderungen am `Dockerfile` holen + ```bash + git pull + ``` + +2. Sicherstellen, dass die neuen Dateien lokal da sind + - Prüfe `.devcontainer/Dockerfile` auf einen neuen Eintrag zu + ``` + # Node.js 24 (LTS) installieren + ``` + +3. Dev-Container neu bauen + - In VS Code: `F1` → **Dev Containers: Rebuild Container** + - oder über die Statusleiste → **Rebuild Container** + +4. Testen der neuen NodeJS-Installation + ```bash + node --version + ``` + Es sollte folgendes ausgegeben werden: + ```bash + v24.11.1 + ``` + +## 4. Javascript-Übung: Grundlagen + +**Aufgabenstellung**: Machen Sie sich zunächst mit den Grundlagen der Programmiersprache vertraut und schreiben Sie dann ein Programm, das über ein vorgegebenes Array von Zahlen iteriert und für jede Zahl ausgibt: + - "Null" wenn die Zahl 0 ist + - "Gerade Zahl" wenn die Zahl gerade ist + - "Ungerade Zahl" wenn die Zahl ungerade ist + +*Ausgangsdaten*: +```js +const zahlen = [38, 0, 226, 384, 111, 500383]; +``` + +#### Arbeitsschritte +1. Arbeiten Sie mindestens die folgenden Kapitel auf [Javascript Tutorial](https://www.w3schools.com/js/default.asp) durch: + - JS Syntax + - JS Variables + - JS If Conditions + - JS Loops +2. Verwenden Sie zur Lösung der Aufgabe eine **for‑Schleife** und den **ternären Operator**. +3. _Tipp_: `zahlen.length` liefert die aktuelle Länge des Arrays. + +## 5. Javascript-Übung: Arrow-Function + +**Aufgabenstellung**: Die Produktdaten eines kleinen Online-Supermarkts liegen als Array von Objekten vor, jedes Objekt enthält den Namen und den Preis eines Produkts. Schreiben Sie eine kleine Javascript-Funktion, die ein neues Array erstellt, in dem alle Preise um 10 % reduziert sind. Die Preise sollen dabei auf zwei Nachkommastellen gerundet werden. + +*Ausgangsdaten*: + +```json +[ + { "produkt": "Joghurt", "preis": 2.49 }, + { "produkt": "Brot", "preis": 3.29 }, + { "produkt": "Käse", "preis": 8.99 }, + { "produkt": "Duschgel","preis": 2.79 } +] +``` + +#### Arbeitsschritte +1. Verwenden Sie `map`, um ein neues Array zu erzeugen. +2. Nutzen Sie eine Arrow-Function, um den Rabatt zu berechnen. +3. Mit `.toFixed(2)` können Sie die Preise auf zwei Nachkommastellen formatieren. +4. Geben Sie das neue Array in der Konsole aus. + +## 6. Go-Übung: CORS + +_Keine Abgabe erforderlich_ + +**Aufgabenstellung**: Erweitern Sie die beiden serverseitigen Go-Programme zur Workshop-Anmeldung aus den vorangegangen Übungsblättern 07 und 08 so, dass beim Ausführen der "Try Out"-Funktion in der SwaggerUI-Preview kein CORS-Fehler mehr auftaucht. + +#### Arbeitsschritte + +1. Fügen Sie folgende Zeile am Anfang in Ihrer Handler `func` oder in der `ServeHTTP`-Funktion ihres `http.Handler` auf: + + ```go + w.Header().Set("Access-Control-Allow-Origin", "*") + w.Header().Set("Access-Control-Allow-Methods", "GET, POST, OPTIONS") + w.Header().Set("Access-Control-Allow-Headers", "Content-Type") + + if r.Method == "OPTIONS" { + w.WriteHeader(http.StatusNoContent) + return + } + ``` + +2. Testen Sie Ihr(e) Programm(e) mit dieser [Workshop-API](workshop-api.json). \ No newline at end of file diff --git a/web/09/hobbiesapi.json b/web/09/hobbiesapi.json new file mode 100644 index 0000000..46b295c --- /dev/null +++ b/web/09/hobbiesapi.json @@ -0,0 +1,129 @@ +{ + "openapi": "3.0.0", + "info": { + "title": "Hobbies API", + "version": "1.0.0" + }, + "servers": [ + { + "url": "http://localhost:8080" + } + ], + "paths": { + "/insert": { + "post": { + "summary": "Erstellt eine:n neue:n Benutzer:in mit einer Liste von Hobbies", + "requestBody": { + "description": "Name und Hobbies des neuen Benutzers/der neuen Benutzerin", + "required": true, + "content": { + "application/x-www-form-urlencoded": { + "schema": { + "$ref": "#/components/schemas/Hobbies" + } + } + } + }, + "responses": { + "200": { + "$ref": "#/components/responses/SuccessResponse" + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "405": { + "$ref": "#/components/responses/MethodNotAllowedResponse" + } + } + } + }, + "/update": { + "post": { + "summary": "Aktualisiert eine:n vorhandene:n Benutzer:in mit einer Liste von Hobbies", + "requestBody": { + "description": "Name und Hobbies des/der vorhandenen Benutzer:in", + "required": true, + "content": { + "application/x-www-form-urlencoded": { + "schema": { + "$ref": "#/components/schemas/Hobbies" + } + } + } + }, + "responses": { + "200": { + "$ref": "#/components/responses/SuccessResponse" + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" + }, + "405": { + "$ref": "#/components/responses/MethodNotAllowedResponse" + } + } + } + } + }, + "components": { + "schemas": { + "Hobbies": { + "type": "object", + "properties": { + "name": { + "type": "string", + "example": "Lea" + }, + "hobby": { + "type": "array", + "items": { + "type": "string" + }, + "example": [ + "reiten", + "backen" + ] + }, + "alter": { + "type": "integer", + "example": 23 + } + } + } + }, + "responses": { + "SuccessResponse": { + "description": "Success", + "content": { + "text/html": { + "schema": { + "type": "string" + } + } + } + }, + "BadRequestResponse": { + "description": "Bad Request", + "content": { + "text/html": { + "schema": { + "type": "string", + "example": "Kein POST-Formular gesendet" + } + } + } + }, + "MethodNotAllowedResponse": { + "description": "Method not allowed", + "content": { + "text/html": { + "schema": { + "type": "string", + "example": "Nur POST-Methode erlaubt." + } + } + } + } + } + } +} \ No newline at end of file diff --git a/web/09/workshop-api.json b/web/09/workshop-api.json new file mode 100644 index 0000000..193a7c0 --- /dev/null +++ b/web/09/workshop-api.json @@ -0,0 +1,119 @@ +{ + "openapi": "3.0.0", + "info": { + "title": "Workshop API", + "version": "1.0.0" + }, + "servers": [ + { + "url": "http://localhost:8080" + } + ], + "paths": { + "/registrierung": { + "post": { + "summary": "Sends all information needed for registering at a workshop", + "requestBody": { + "required": false, + "content": { + "application/x-www-form-urlencoded": { + "schema": { + "$ref": "#/components/schemas/RegistrierungForm" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/RegistrierungForm" + } + } + } + }, + "responses": { + "200": { + "description": "Success", + "content": { + "text/html": { + "schema": { + "type": "string" + } + } + } + }, + "400": { + "description": "Bad Request", + "content": { + "text/plain": { + "schema": { + "type": "string", + "example": "Kein Formular gesendet" + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "RegistrierungForm": { + "type": "object", + "required": [ + "vorname", + "nachname", + "agb", + "format" + ], + "properties": { + "vorname": { + "type": "string", + "example": "Zoya" + }, + "nachname": { + "type": "string", + "example": "Akhtar" + }, + "email": { + "type": "string", + "example": "z.akhtar@test.de" + }, + "telefon": { + "type": "string", + "example": "Zoya" + }, + "sessions": { + "type": "array", + "items": { + "type": "string", + "example": "vormittag" + }, + "example": [ + "vormittag", + "nachmittag" + ] + }, + "agb": { + "type": "string", + "enum": ["on","ja"], + "example": "on" + }, + "newsletter": { + "type": "string", + "enum": ["on","ja"], + "example": "ja" + }, + "equipment": { + "type": "string", + "enum": ["on","ja"], + "example": "ja" + }, + "format": { + "type": "string", + "enum": ["online","praesenz"], + "example": "online" + } + } + } + } + } +} \ No newline at end of file