Backend
Motivation
Frontends können einige Dinge nicht
- Authentifizierung
- Autorisierung
- Datenspeicherung
- API Key Verwaltung
Architektur
Kommunikation üblicherweise über http
HTTP

URL - Uniform Resource Locator
protocol://hostname:port/path?field=value
Request
GET http://www.htlstp.ac.at/logo
Accept: image/webp, image/apng, image/*, */*;q=0.8
POST http://www.htlstp.ac.at/api/teachers/
Content-Type: application/json
{
"name": "SCRE",
"dept": "IF"
}
Response
HTTP/1.1 200 OK
Server: nginx
Date: Mon, 18 May 2020 18:08:47 GMT
Content-Type: image/png
Content-Length: 4663
Connection: keep-alive
Expires: Mon, 25 May 2020 04:35:30 +0200
PNG
IHDR
N£%É;%ÚCl³Úí:º0ºRî`Ýze++¡·1Úqõ.¥ôBëm7¹·îd%á
...Request Methoden
- GET
GET http://www.appdomain.com/users GET http://www.appdomain.com/users/123 GET http://www.appdomain.com/users?size=20&page=5- lädt die angegebene Resource
- sollte bei jedem Aufruf dasselbe Resultat liefern
- DELETE
DELETE http://www.appdomain.com/users/123- löscht die angegebene Resource
- POST
POST http://www.appdomain.com/users Content-Type: application/json {resource}- Resource im RequestBody speichern
- PUT/PATCH
PUT http://www.appdomain.com/users/123 Content-Type: application/json {resource}- Resource im RequestBody unter Request-URI ersetzen/updaten
Status Codes
- 200 - OK
- 400 - Bad Request
- Request fehlerhaft, später sicher Fehler
- Bestellt Kebab bei McDonalds
- 500 - Internal Server Error
- Request ok, Serverfehler, später vielleicht Erfolg
- Bestellt Pommes, die sind noch nicht fertig
- 201 - Created
- 204 - No Content
- nach DELETE
- 404 - Not Found
node Server
import {createServer, IncomingMessage, ServerResponse} from "http";
const port = 3000
const server = createServer(
(request: IncomingMessage, response: ServerResponse) => {
response.writeHead(200, {'Content-Type': 'text/html'});
response.write(`
<html>
<body>Hello World</body>
</html>
`);
response.end();
}
);
server.listen(port, () => console.log(`Server listens on ${port}`))
GET localhost:3000 => Hello World
POST localhost:3000 => Hello World
DELETE localhost:3000/what/ever => Hello World
Routing
if (request.method === 'GET' && request.url === '/hello')
// send hello world
if (request.method === 'GET' && request.url === '/login')
// login
if (request.method === 'POST' && request.url === '/transmit') {
// Daten kommen nicht komplett an, sondern in chunks
let rawData = '';
request.on('data', chunk => {
rawData += chunk
});
request.on('end', () => {
// use rawData
});
}
Form Data
<form action='/submit' method='POST'>
<label for='name'>Name:</label>
<input type='text' id='name' name='name'>
<label for='email'>Email:</label>
<input type='email' id='email' name='email'>
</form>
POST /submit HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 42
name=scre&email=christoph.schreiber@htlstp.at
name=value&name=value&name=value ...
CSR vs SSR

Content loading
- SSR ✅
- CSR Frontend lädt Daten dynamisch vom Backend
- CRUD-Application (Create, RRead, UUpdate, DDelete)
- Standardformat JSON(Javascript Object Notation)
{
"grade": 3,
"mandatory": true,
"teacher": "SCRE",
"subject": {
"title": "Web und Mobile Computing",
"short": "WMC"
},
"content": [
"Frontend",
"Backend"
],
"technologies": [
{
"type": "IDE",
"title": "WebStorm"
},
{
"type": "Frontend",
"title": "Angular"
}
]
}
Layered Architecture
Express
const port = 3000;
const app = express();
app.get('/', (req, res) => {
res.send('Hello World');
});
app.post('/transmit', (req, res) => {
let data = req.body;
res.status(200)
.json({'received': data});
});
app.listen(port, () => {
console.log(`Server listens on ${port}`);
});
Error Handling
Error ⟹ 500 Internal Server Error
app.post('/students', (req, res) => {
let student = req.body;
try {
let saved = service.save(student); // throw new Error('invalid')
res.status(201)
.json(saved);
} catch(err: any) { // ohne catch 500
res.status(400)
.json({error: err.message}); // 'invalid'
}
});
<!-- .element: class="fragment "-->
Interfaces
export interface Student {
id: number,
firstName: string,
lastName: string
}
⟹
[
{
"id": 1, "firstName": "Alfred", "lastName": "Adler"
},
{
"id": 2, "firstName": "Bernd", "lastName": "Bauer"
}
]