From 5cbe3c0553d15ff0277716b16c871a66b1a070ef Mon Sep 17 00:00:00 2001 From: Teena Steger Date: Tue, 12 May 2026 15:18:24 +0200 Subject: [PATCH] 09: Labor --- web/09/labor/db/09_aufgaben.md | 41 +++++++++ web/09/labor/db/anleitung_db.md | 23 +++++ web/09/labor/db/create_personen.sql | 5 ++ web/09/labor/db/hobbiesapi.json | 129 ++++++++++++++++++++++++++++ web/09/labor/db/insert_personen.sql | 1 + web/09/labor/db/select_personen.sql | 1 + web/09/labor/db/workshop-api.json | 119 +++++++++++++++++++++++++ 7 files changed, 319 insertions(+) create mode 100644 web/09/labor/db/09_aufgaben.md create mode 100644 web/09/labor/db/anleitung_db.md create mode 100644 web/09/labor/db/create_personen.sql create mode 100644 web/09/labor/db/hobbiesapi.json create mode 100644 web/09/labor/db/insert_personen.sql create mode 100644 web/09/labor/db/select_personen.sql create mode 100644 web/09/labor/db/workshop-api.json diff --git a/web/09/labor/db/09_aufgaben.md b/web/09/labor/db/09_aufgaben.md new file mode 100644 index 0000000..2e01283 --- /dev/null +++ b/web/09/labor/db/09_aufgaben.md @@ -0,0 +1,41 @@ +# Übungsblatt 09 + +## 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. + +## 2. Go-Übung: Datenbank UPDATE + +**Aufgabenstellung**: Erweitern Sie das Programm aus Aufgabe 1 um einen neuen Endpunkt `/update`, der einen vorhandenen Datensatz in der Datenbank aktualisiert. + +### 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. HTML-Übung: Formular + +**Aufgabenstellung**: Schreiben Sie ein HTML-Formular, dass die Schnittstelle [Swagger-API](hobbiesapi.json) implementiert und Benutzereingaben an das in Aufgabe 1 + 2 implementierte Backend sendet. + +## 4. 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/labor/db/anleitung_db.md b/web/09/labor/db/anleitung_db.md new file mode 100644 index 0000000..04f1759 --- /dev/null +++ b/web/09/labor/db/anleitung_db.md @@ -0,0 +1,23 @@ +# Tooling für die Entwicklung mit einer PostGreSQL-DB + +Diese Anleitung beschreibt die Schritte zur Verbindung mit einer PostGreSQL-DB sowie das Erstellen von Tabellen mit Hilfe der VS Code Extension _PostgreSQL_ und der im Dev-Container enthaltenen Datenbank. + +## Neue Verbindung + +1. Prüfen Sie, ob Sie sich im Dev-Container befinden +2. Klicken Sie auf das PostGreSQL-Symbol (VS Code Extension) in der Activity Bar (default: linke Leiste) +3. Wählen Sie "Add New Connection" und "CONNECTIONS" in der Primary Side Bar (meistens: links) + 1. Füllen Sie die geforderten Felder aus. Sie finden die Daten zu Ihrer Datenbank-Installation in der Datei `.env` innerhalb des `.devcontainer`- Ordners. + 2. Testen Sie die Verbindung ("Test Connection") + 3. Vergeben Sie einen geeigneten Namen und speichern Sie die Verbindung ("Save & Connect") + +## Tabellen +4. Öffnen Sie die Datei `create_personen.sql`. +5. Auf der rechten Seite der Tab-Leiste erscheinen nun mehrere Symbole. Wählen Sie "Connect" aus und geben Sie ggf. Ihr Datenbank-Passwort ein (`POSTGRES_PASSWORD` in `.env`) +6. Wählen Sie nun das Symbol für "Change PostGreSQL Database" aus und wählen Ihre Datenbank aus (`POSTGRES_DB` in `.env`) +7. Wählen Sie nun das Symbol für "Execute PostGreSQL Query" aus: Es wird eine neue Tabelle in Ihrer Datenbank erstellt. + +## Einfügen und Anzeigen +8. Führen Sie die Schritte 5.-7. nun auch für die Dateien `insert_personen.sql` und `select_personen.sql` durch. +9. Alternativ oder zusätzlich können Sie natürlich auch eigene Queries ausführen. + diff --git a/web/09/labor/db/create_personen.sql b/web/09/labor/db/create_personen.sql new file mode 100644 index 0000000..27ac3bb --- /dev/null +++ b/web/09/labor/db/create_personen.sql @@ -0,0 +1,5 @@ +CREATE TABLE personen ( + name TEXT NOT NULL, + hobbies TEXT, + alter SMALLINT +); \ No newline at end of file diff --git a/web/09/labor/db/hobbiesapi.json b/web/09/labor/db/hobbiesapi.json new file mode 100644 index 0000000..46b295c --- /dev/null +++ b/web/09/labor/db/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/labor/db/insert_personen.sql b/web/09/labor/db/insert_personen.sql new file mode 100644 index 0000000..987a7a6 --- /dev/null +++ b/web/09/labor/db/insert_personen.sql @@ -0,0 +1 @@ +INSERT INTO personen (name, hobbies, alter) VALUES ('Siri', 'Lesen, Wandern, Kochen', 14),('Alexa', 'Kochen, Gitarre spielen', 11); \ No newline at end of file diff --git a/web/09/labor/db/select_personen.sql b/web/09/labor/db/select_personen.sql new file mode 100644 index 0000000..6aa87aa --- /dev/null +++ b/web/09/labor/db/select_personen.sql @@ -0,0 +1 @@ +SELECT * FROM personen; \ No newline at end of file diff --git a/web/09/labor/db/workshop-api.json b/web/09/labor/db/workshop-api.json new file mode 100644 index 0000000..60c76d7 --- /dev/null +++ b/web/09/labor/db/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": ["ja"], + "example": "ja" + }, + "newsletter": { + "type": "string", + "enum": ["ja"], + "example": "ja" + }, + "equipment": { + "type": "string", + "enum": ["ja"], + "example": "ja" + }, + "format": { + "type": "string", + "enum": ["online","praesenz"], + "example": "online" + } + } + } + } + } +} \ No newline at end of file