Backend
DVOP3 WBB
Bc. Matěj Cajthaml ©
Smíchovská střední průmyslová
škola a gymnázium
Motivace a informace na začátek
- v této lekci se nebudeme zaměřovat na jeden určitý jazyk
- budeme si ukazovat základní principy v různých jazycích a knihovnách
- sami byste již měli mít zkušenosti s nějakým jazykem — C#, JS, ...
Webový server
- server, který umí komunikovat nad HTTP
- existují
hloupé
knihovny, které vytváří jen základy
- pokročilé se starají i o hlavičky a další věci
Jednoduché webové servery
- často pouze jeden callback
- získáváme požadavek a odpověď, kterou můžeme poslat
- můžeme si vytvořit vlastní nástavbu — nebo knihovny
Porty
- každý server běží na nějakém portu
- porty jsou čísla od 0 do 65535
- určité rozsahy jsou rezervované a nelze je použít
- pro HTTP klasicky 80 a 443
- knihovny často poskytují možnost nastavit certifikáty
Většina služeb avšak běží na jiném portu než 80 a 443. A navíce nejsou k dispozici na veřejném internetu. Proč?
Endpoint
- viz úvod API
- může být jakýkoliv zdroj, který je dostupný přes HTTP
- často se jedná o URL adresu
- definice v souladu s REST
Endpoint
- pro nás prozatím jen metoda + URL
- např.
GET /api/v1/users
Dobré návyky
- názvy endpointů v stejném čísle (množné vs jednotné)
- často problémy s věcmi, které existují opravdu jen jednou
- reprezentované entity v endpointu nejsou dostupné na jiném endpointu
Parametry endpointů
- viz úvod do API
- parametry:
- v cestě v dokumentaci pomocí
:var
- do URL endpointu se query nezapisují a neměly by být povinné
- v body spíše jen data, ne parametry
Návyky ve filtrování, řazení a stránkování
- filtrování = jen ty vysledky, které něco splňují
- řazení = v jakém pořadí se mají výsledky vrátit
- stránkování = jaké výsledky se mají vrátit
Proč bychom chtěli mít stránkování? Je nutné?
Návyky ve filtrování, řazení a stránkování
- filtrování =
?surname=cajthaml
- filtrování =
?filter-field=all&filter-value=cajthaml
- řazení =
?sort=name
- řazení =
?sort=name&order=desc
- stránkování =
?page=1&limit=10
Validace parametrů
- parametry by měly být validovány
- pokud nejsou validní, je standardem provést akci se základními hodnotami
- pokud je to možné, je vhodné vrátit chybový kód
Regulární výrazy
- pokročilý způsob validace
- jednoduchá validace, podporuje řada knihoven
Volání HTTP v JavaScriptu
Volání HTTP v JavaScriptu
- můžeme použít: fetch, XMLHttpRequest, axios, ...
- problémy s CORS (více později)
Fronta úkolů
Práce
Vytvořte Web API, které má dva endpointy:
/request — dá úkol do fronty ke zpracování, vrací id
/:id — vrátí řešení úkolu podle id
Minulou hodinu jsme měli problém s posíláním požadavků v prohlížeči. Kdo nám je zakázal posílat?
Jaké problémy by mohlo způsobit to, že dovolíme jakékoliv doméně posílat požadavky najakoukoliv doménu?
CORS
- = Cross-origin resource sharing
- mechanismus zabezpečení webové stránky
- každý server si může říct, jaké domény mají k datům přístup
- prohlížeč potom tyto nastavení kontroluje
Co znamená same-origin policy? Jak splnit jeho požadavky bez CORS?
CORS hlavičky
Access-Control-Allow-Origin: https://cajthaml.eu
Access-Control-Allow-Origin: *
- odesílá server např. při požadavku
OPTIONS
Hlavičky
Práce
Zjistěte, k čemu slouží:
Access-Control-Allow-Headers
Access-Control-Allow-Methods
Jak v CORS povolíme více domén?
CORS kontroluje prohlížeč. Může jej kontrolovat jakýkoliv klient, např. i backendový server?
CORS
Práce
Ve vámi vybraném jazyce a knihoven vytvořte server, který bude mít CORS povolené pro všechny domény.
Content Security Policy
Práce
Zjistěte si, co je to Content Security Policy. Jak se liší oproti CORS?
Volání API ze stránek
Práce
Vytvořme stránku a příslušné API složené ze dvou částí:
- přidávání dat: pomocí formuláře přidáme data
- čtení dat: můžeme data zobrazit
Hlavičky na obsah dat
- při posílání dat je nutné poslat hlavičku
Content-Type
- při získávání dat je nutné poslat hlavičku
Accept
- pokud zašleme, server může poslat data ve formátu, který chceme
- pro zpracování dat od klienta je často nutné mít tzv.
body-parser
Používané formáty
- JSON —
application/json
- XML —
application/xml
- HTML —
text/html
- text —
text/plain
JSON
- parsování:
JSON.parse()
- serializace:
JSON.stringify()
DTO
- DTO = Data Transfer Object
- objekt, který reprezentuje data, která se posílají — nemají žádné netriviální datové typy
- často se používá pro validaci dat a na to, aby obě strany věděly, co se posílá
- DTO se často zveřejňují jako rozhraní
Co kdybychom nechtěli mít více serverů na API a hosting stránek? Lze to udělat?
A co když to nebude jeden soubor, ale více souborů a assetů?
Hostování stránek
Práce
Zhostujeme si naší statickou stránku/soubory.
Souborový systém
Práce
Ve vámi vybraném jazyce a knihovně na servery zjistěte, jak se pracuje se soubory. Vytvořte API, které bude umět posílat obsah souboru a nahrávat obsah souborů.
Další práce
- TODO list
- Fronta a její zpracování
- Soubory
Middleware
- jedná se o funkci
- přijímá většinou 3 parametry:
- request — požadavek
- response — odpověď
- next — další funkci ve volání
Kaskáda
- jednotlivé funkce jsou volány postupně
- při zavolání funkce
next() se zavolá další funkce v pořadí
- ukončuje se taktéž pomocí volání
res.send() a obdobných
Využití middlewares
- spouštění kódu
- validace požadavků
- logování
- autentizace a autorizace
Definice funkce / v Node.js
Pokročilejší funkce / v Node.js
Middleware se mohou používat na různých místech — a to na jednom endpointu, na všech endpointech, ale i mimo je.
Middleware
Práce
Ve vámi vybraném jazyce a knihovně na servery vytvořte middleware a zaregistrujte ho na celou aplikaci a poté na jeden endpoint.
Použití pomocí use / v Node.js
Použití v endpointu / v Node.js
Pokročilá kaskáda / v Node.js
Middleware umí zamítnout požadavek a nebo požadavek či odpověď serveru změnit a předávat tím data do dalších volání middlewares.
Širší zaměření
- middleware nejsou jen na backendu
- často jsou i po komunikaci se serverem, např.:
- teoreticky jsou i na frontendu
Máme tři různé middleware, které mají totožný kód, pouze se jim mění jedna věc — hlavička. Je možnost toto zjednodušit?
Pokročilé middleware s parametrem
Dříve uvedený middleware není obecný. Proč? Jak to opravíme?
Pokročilé middleware
Práce
Opravte výše uvedený middleware tak, aby příjímal parametr pro požadovanou hlavičku.
Pokročilé middleware s polem
Práce
Opravte výše uvedený middleware tak, aby příjímal parametr a nebo pole pro požadované hlavičky.
Aktuálně, když použijeme app.use, tak je middleware volána na všech následujících endpointech. Co bychom dělali, kdybychom ji na jednom endpointu nechtěli?
Routery
- způsob, jak rozdělit express aplikaci do podčástí
- každá část odpovídá na nějaký záčátek url, např.
/user
- uvnitř jsou
schovány
middleware a nedostávají se mimo
Vytvoření routeru / v Node.js
Zamezení middleware / v Node.js
Routery se používají i na rozdělení aplikace do menších částí — souborů.
Rozdělení routerů
Práce
Pro každý router vytvořte samostatný soubor a vytvořte v něm router. Vytvořte všechny potřebné endpointy a připojte je do hlavního routeru.
Základní autentifikace
Práce
Vytvořte API, které bude v hlavičce přijímat přístupové údaje, které budou potřeba pro jakoukoliv komunikaci mimo endpoint GET /ping.
API bude sloužit ke správně neurčitých dat. Tedy minimálně CRUD.
Rozložení aplikace
- aplikaci je nutné rozdělit na menší (logické) části
- často rozdělujeme routery, které můžeme na sebe propojovat
- soubory s routery poté rozdělujeme na jednotlivé endpointy
/
├── src/
│ └── controllers/
│ ├── user/
│ │ ├── endpoints/
│ │ │ ├── getOne.js
│ │ │ ├── getAll.js
│ │ │ ├── updateOne.js
│ │ │ └── getFriendsForOne.js
│ │ └── user.js
│ └── grades/
│ └── ...
└── main.js
Jaké jsou nevýhody a výhody tohoto systému? Jak ho zlepšit?
Jak budeme tvořit další logické části — např. pomocné funkce, databázové entity, servisy a další věci?
Teorie vrstvení
- moderní API nejsou jen o tom, že mají reagovat na určité endpointy
- často se jedná o pokročilé procesy, které zařizují věci na jiných zdrojích
- při návrhu aplikace je nutné přemýšlet o vrstvení
Vrstvení
- způsob rozdělit aplikaci na jednotlivé vrstvy — layers
- často se zaměnují za tiers — které reprezuntují fyzický stav
- vrstva má vždy za úkol jednu část, kterou zpracovává, např:
- přijmutí dat a jejich validace
- získáni či úprava dat z databáze
- zpracování požadavku
- každá vrstva získává data z nižší vrstvy — nelze to naopak
Toto vrstvení používáme proto, aby nenastalo to, co děláme: endpointy řeší vše
Kolik vstvev by měla mít aplikace?
Často se používají různé modifikace, například to, že můžeme komunikovat s jakoukoliv vrstvou a nebo třeba vrstvy přeskakovat. Proč?
Základní třívrstvá architektura
- prezentační vrstva (presentation layer)
- aplikační vrstva (business layer)
- datová vrstva (data access layer)
Často se používá tzv. model-view-controller (MVC) či model-view-presenter (MVP). Jak se liší oproti třívstvému návrhu?
Vrstvy, MVC či MVP nelze zaměňovat se službami — services. Jak se liší?
Microservices
- moderní návrh aplikací
- jedna aplikace se rozdělí do více menších aplikací
- prezentační vrstva poté komunikuje s jednotlivými aplikacemi
- např.: přihlašování, nahrávání videa, komentování
- jaké jsou výhody a nevýhody?
Template engine
- knihovna, která má za úkol vykreslovat různé šablony
- často pro HTML — generujeme stránky
- požadavek ⇉ vykreslení ⇉ prohlížeč
- předáváme proměnné, které šablony modifikují
Ukázky
- pug
- ejs
- handlebars
- chameleon
- razor
Další enginy
Práce
Nalezněte další template engines, které vaše knihovna / jazyk podporuje. Pokuste se vytvořit jednoduchou stránku.
Můžeme věřit vstupu od uživatele? Proč?
Validace dat
- spousta možností validace
- express/node.js: joi
- c#/asp.net: data annotations
- python: jsonschema
Nahrávání souborů
- spousta knihoven
- často problém s parsováním form data formátem
Nahrávání
Práce
Zkusme vytvořit aplikaci, ve které půjde nahrávat a zobrazovat soubory.
Používat šifrování — TLS / SSL.
Problémy s porty.
Bezpečnostní hlavičky
Práce
Nalezněte zdroje, které vám řeknou, jaké bezpečnostní hlavičky by měla mít vaše aplikace.
Používat limitery — zamezit brute-force atakům.
Používat ověřené a nové verze knihoven.
Vždy validovat vstup uživatele.
Na jakém portu obyčejně běží HTTP / HTTPS?
Může bězet na jednom serveru více domén?
Backend většinou běží na nějakém (klidně nezabezpečeném) portu, který je díky firewallu nedostupný z internetu.
Hlavní správce web serveru (nginx, apache2) poté posílá požadavky z domény na určitý port a vrací požadavek.
Co když zavřeme terminál?
Správce procesů
- existuje spousta
- starají se o to, aby proces vždy běžel
- když spadne — restartuje se
- když se server zapne — zapne se
- docker, pm2, systemd
- docker viz později
Opakování
- endpointy
- parametry
- middleware
- CORS
- vrstvení
- template engines
Děkuji za pozornost!
- matej.cajthaml@ssps.cz
- https://ssps.cajthaml.eu/