Initial commit: IHK Ausbildung materials
This commit is contained in:
272
1-Ausbildungsjahr/LF6-Webanwendungen/LF6-03-Backend.md
Normal file
272
1-Ausbildungsjahr/LF6-Webanwendungen/LF6-03-Backend.md
Normal file
@@ -0,0 +1,272 @@
|
||||
# 6.3 Backend-Entwicklung
|
||||
|
||||
## Server-Grundlagen
|
||||
|
||||
### Client-Server-Architektur
|
||||
|
||||
```
|
||||
Webanwendung - Architektur
|
||||
┌─────────────┐ HTTP ┌─────────────┐
|
||||
│ Browser │ ◄──────────────►│ Server │
|
||||
│ (Frontend) │ │ (Backend) │
|
||||
└─────────────┘ └──────┬──────┘
|
||||
│
|
||||
┌─────┴─────┐
|
||||
│ Datenbank │
|
||||
└───────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Node.js
|
||||
|
||||
### Grundlagen
|
||||
|
||||
```javascript
|
||||
// Einfacher Server
|
||||
const http = require('http');
|
||||
|
||||
const server = http.createServer((req, res) => {
|
||||
res.writeHead(200, { 'Content-Type': 'text/html' });
|
||||
res.end('<h1>Hallo Welt!</h1>');
|
||||
});
|
||||
|
||||
server.listen(3000, () => {
|
||||
console.log('Server läuft auf Port 3000');
|
||||
});
|
||||
```
|
||||
|
||||
### Express.js
|
||||
|
||||
```javascript
|
||||
const express = require('express');
|
||||
const app = express();
|
||||
|
||||
// Middleware
|
||||
app.use(express.json());
|
||||
|
||||
// GET-Route
|
||||
app.get('/api/benutzer', (req, res) => {
|
||||
res.json([
|
||||
{ id: 1, name: 'Max' },
|
||||
{ id: 2, name: 'Anna' }
|
||||
]);
|
||||
});
|
||||
|
||||
// POST-Route
|
||||
app.post('/api/benutzer', (req, res) => {
|
||||
const neuerBenutzer = req.body;
|
||||
// Speichern...
|
||||
res.status(201).json(neuerBenutzer);
|
||||
});
|
||||
|
||||
app.listen(3000);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## REST-API
|
||||
|
||||
### REST-Prinzipien
|
||||
|
||||
```
|
||||
REST - Grundsätze
|
||||
├── Ressourcen-orientiert (Nomen)
|
||||
├── Stateless (keine Session)
|
||||
├── Einheitliche Schnittstelle
|
||||
├── Client-Server-Trennung
|
||||
└── Cache-fähig
|
||||
```
|
||||
|
||||
### HTTP-Methoden
|
||||
|
||||
| Methode | CRUD | Beschreibung |
|
||||
|---------|-----|-------------|
|
||||
| GET | Read | Daten abrufen |
|
||||
| POST | Create | Daten erstellen |
|
||||
| PUT | Update | Daten vollständig ersetzen |
|
||||
| PATCH | Update | Daten teilweise ändern |
|
||||
| DELETE | Delete | Daten löschen |
|
||||
|
||||
### API-Endpunkte
|
||||
|
||||
```
|
||||
Beispiel: Benutzer-Ressource
|
||||
|
||||
GET /api/benutzer → Alle Benutzer
|
||||
GET /api/benutzer/:id → Ein Benutzer
|
||||
POST /api/benutzer → Benutzer erstellen
|
||||
PUT /api/benutzer/:id → Benutzer ersetzen
|
||||
PATCH /api/benutzer/:id → Benutzer ändern
|
||||
DELETE /api/benutzer/:id → Benutzer löschen
|
||||
```
|
||||
|
||||
### Response-Format
|
||||
|
||||
```json
|
||||
// Erfolgreich (200 OK)
|
||||
{
|
||||
"status": "success",
|
||||
"data": {
|
||||
"id": 1,
|
||||
"name": "Max"
|
||||
}
|
||||
}
|
||||
|
||||
// Erfolg (201 Created)
|
||||
{
|
||||
"status": "success",
|
||||
"message": "Benutzer erstellt",
|
||||
"data": {
|
||||
"id": 2
|
||||
}
|
||||
}
|
||||
|
||||
// Fehler (400 Bad Request)
|
||||
{
|
||||
"status": "error",
|
||||
"message": "Ungültige E-Mail-Adresse"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Datenbank-Zugriff
|
||||
|
||||
### MySQL mit Node.js
|
||||
|
||||
```javascript
|
||||
const mysql = require('mysql2/promise');
|
||||
|
||||
async function main() {
|
||||
const connection = await mysql.createConnection({
|
||||
host: 'localhost',
|
||||
user: 'root',
|
||||
password: 'passwort',
|
||||
database: 'webshop'
|
||||
});
|
||||
|
||||
// Daten abfragen
|
||||
const [rows] = await connection.execute(
|
||||
'SELECT * FROM benutzer WHERE id = ?',
|
||||
[1]
|
||||
);
|
||||
console.log(rows);
|
||||
|
||||
await connection.end();
|
||||
}
|
||||
|
||||
main();
|
||||
```
|
||||
|
||||
### MongoDB mit Node.js
|
||||
|
||||
```javascript
|
||||
const mongoose = require('mongoose');
|
||||
|
||||
// Verbindung
|
||||
mongoose.connect('mongodb://localhost:27017/webshop');
|
||||
|
||||
// Schema
|
||||
const benutzerSchema = new mongoose.Schema({
|
||||
name: String,
|
||||
email: { type: String, unique: true },
|
||||
alter: Number
|
||||
});
|
||||
|
||||
const Benutzer = mongoose.model('Benutzer', benutzerSchema);
|
||||
|
||||
// Daten speichern
|
||||
const neuerBenutzer = new Benutzer({
|
||||
name: 'Max',
|
||||
email: 'max@example.com'
|
||||
});
|
||||
await neuerBenutzer.save();
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Session und Authentifizierung
|
||||
|
||||
### JWT (JSON Web Token)
|
||||
|
||||
```javascript
|
||||
const jwt = require('jsonwebtoken');
|
||||
|
||||
// Token erstellen
|
||||
function createToken(user) {
|
||||
return jwt.sign(
|
||||
{ id: user.id, email: user.email },
|
||||
'geheimer-schluessel',
|
||||
{ expiresIn: '24h' }
|
||||
);
|
||||
}
|
||||
|
||||
// Token prüfen
|
||||
function verifyToken(token) {
|
||||
try {
|
||||
return jwt.verify(token, 'geheimer-schluessel');
|
||||
} catch (err) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// Middleware
|
||||
function authenticate(req, res, next) {
|
||||
const token = req.headers.authorization?.split(' ')[1];
|
||||
const decoded = verifyToken(token);
|
||||
|
||||
if (!decoded) {
|
||||
return res.status(401).json({ error: 'Nicht autorisiert' });
|
||||
}
|
||||
|
||||
req.user = decoded;
|
||||
next();
|
||||
}
|
||||
```
|
||||
|
||||
### Passwort-Hashing
|
||||
|
||||
```javascript
|
||||
const bcrypt = require('bcrypt');
|
||||
|
||||
// Passwort hashen
|
||||
async function hashPassword(password) {
|
||||
const salt = await bcrypt.genSalt(10);
|
||||
return await bcrypt.hash(password, salt);
|
||||
}
|
||||
|
||||
// Passwort prüfen
|
||||
async function checkPassword(password, hash) {
|
||||
return await bcrypt.compare(password, hash);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## RESTful Best Practices
|
||||
|
||||
### Tipps
|
||||
|
||||
```
|
||||
API-Design - Empfehlungen
|
||||
├── Versionierung: /api/v1/...
|
||||
├── Plural: /benutzer nicht /benutzer
|
||||
├── Filter: /benutzer?alter=25
|
||||
├── Sortierung: /benutzer?sort=name
|
||||
├── Paginierung: /benutzer?page=1&limit=10
|
||||
├── Fehlercodes: HTTP-Statuscodes nutzen
|
||||
└── Dokumentation: OpenAPI/Swagger
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Querverweise
|
||||
|
||||
- [[LF6-02-Frontend|Zurück: Frontend-Entwicklung]]
|
||||
- [[LF6-04-Sicherheit-Web|Nächstes Thema: Web-Sicherheit]]
|
||||
- [[LF3-Datenbanken|Datenbanken]]
|
||||
|
||||
---
|
||||
|
||||
*Stand: 2024*
|
||||
Reference in New Issue
Block a user