first week
This commit is contained in:
commit
ffcc9e1b5c
14 files changed
+1011
No files matched your search
@@ -0,0 +1,87 @@
|
||||
\section{Tárgy bemutatása}
|
||||
|
||||
\begin{frame}{Oktató}
|
||||
\footnotesize
|
||||
Üdvözlünk a \emph{Webtechnológia és webalkalmazás-fejlesztés} tárgy első óráján! Ezt a diasort úgy állítottuk össze, hogy akkor is jól követhető legyen, ha valaki lemaradt az óráról -- minden fogalmat igyekszünk a lehető legrészletesebben, magyarázó szöveggel is ellátni.
|
||||
|
||||
\begin{block}{Elérhetőségek}
|
||||
\textbf{Magda Donát}, mérnökinformatikus BSc
|
||||
\begin{itemize}
|
||||
\item \textbf{E-mail:} magda.donat@sze.hu -- bármilyen kérdéssel, technikai problémával nyugodtan keress meg
|
||||
\item \textbf{Konzultáció:} előre egyeztetve, Google Meet -- ha személyesen szeretnéd átbeszélni a haladásodat
|
||||
\end{itemize}
|
||||
\end{block}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}{Tantárgy célja}
|
||||
\footnotesize
|
||||
A tárgy célja, hogy végigjárjuk egy modern, Javascript/Node.js alapú backend rendszer felépítésének teljes útját: a nyers HTTP-kérések kezelésétől egészen egy biztonságos, adatbázissal és külső szolgáltatásokkal kommunikáló API-ig.
|
||||
|
||||
\begin{itemize}
|
||||
\item Javascript alapú backend fejlesztés elsajátítása -- ugyanazt a nyelvet használjuk, mint amit sokan már a frontendről ismernek
|
||||
\item HTTP/HTTPS alapok, REST API-k és architekturális felépítések megértése
|
||||
\item Adatbázis-kezelés, ORM (Object-Relational Mapping) és a CQRS (Command Query Responsibility Segregation) megközelítés
|
||||
\item Authentikáció, authorizáció és külső szolgáltatások (pl. email küldés, cache) integrálása
|
||||
\item Gyakorlati tapasztalat egy önállóan futtatható backend rendszer elkészítésével
|
||||
\end{itemize}
|
||||
|
||||
\begin{block}{Cél}
|
||||
Az alapoktól (HTTP, Node.js, csomagkezelés) egy teljes, biztonságos backend API-ig -- lépésről lépésre, minden héten egy újabb réteggel bővítve a tudásunkat.
|
||||
\end{block}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}{Tematika -- 1-6. hét}
|
||||
\footnotesize
|
||||
Az első hat hét az alapozásról szól: megismerjük a HTTP protokollt, felépítünk egy REST API-t, és megtanuljuk, hogyan lehet azt egy adatbázissal összekötni.
|
||||
|
||||
\begin{block}{}
|
||||
\begin{tabular}{ll}
|
||||
\textbf{1. hét} & Alapok, Node.js, HTTPS, NPM package manager \\
|
||||
\textbf{2. hét} & REST API, architekturális felépítések, CQRS \\
|
||||
\textbf{3. hét} & Express.js, Routing, Postman, TypeScript \\
|
||||
\textbf{4. hét} & ORM, database connection, CRUD operations \\
|
||||
\textbf{5. hét} & TypeORM, Aggregates, Repositories \\
|
||||
\textbf{6. hét} & \textbf{ZH 1}: Database CRUD, ORM, CQRS + DTOs, Mappers \\
|
||||
\end{tabular}
|
||||
\end{block}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}{Tematika -- 6-13. hét}
|
||||
\footnotesize
|
||||
A második félidőben a biztonságra és a valós, éles rendszerekben elengedhetetlen kiegészítőkre fókuszálunk: bejelentkezés, jogosultságkezelés, emailküldés, teljesítmény.
|
||||
|
||||
\begin{block}{}
|
||||
\begin{tabular}{ll}
|
||||
\textbf{7. hét} & AUTH, OUTH, OAUTH2 \\
|
||||
\textbf{8. hét} & Session, JWT, Cookie \\
|
||||
\textbf{9. hét} & Hash, Middleware, Services \\
|
||||
\textbf{10. hét} & Email sending, Templating \\
|
||||
\textbf{11. hét} & Dependency Injection, Logging \\
|
||||
\textbf{12. hét} & CORS, Redis, External API \\
|
||||
\textbf{13. hét} & Gyakorlás -- teljes API írása (\textbf{NAGY ZH}) \\
|
||||
\end{tabular}
|
||||
\end{block}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}{Teljesítés}
|
||||
\footnotesize
|
||||
A tárgyat két zárthelyi dolgozat (ZH) alapján teljesítjük. A pontszámok összeadódnak, és az alábbi táblázat szerint alakul belőlük az érdemjegy:
|
||||
|
||||
\begin{block}{Pontszámítás}
|
||||
\begin{tabular}{|c|c|}
|
||||
\hline
|
||||
\textbf{Jegy} & \textbf{Pont} \\
|
||||
\hline
|
||||
1 & 0--50 \\
|
||||
2 & 51--62 \\
|
||||
3 & 63--74 \\
|
||||
4 & 75--86 \\
|
||||
5 & 87--100 \\
|
||||
\hline
|
||||
\end{tabular}
|
||||
\end{block}
|
||||
|
||||
\begin{alertblock}{Megajánlott jegy}
|
||||
Megajánlott jegy ZH pontokból szerezhető, mely a vizsga pontozásával megegyezően kerül értékelésre -- vagyis ha a féléves munkád elég jó, a vizsgaidőszakban nem kell feltétlenül vizsgáznod.
|
||||
\end{alertblock}
|
||||
\end{frame}
|
||||
@@ -0,0 +1,205 @@
|
||||
\section{HTTP és HTTPS}
|
||||
|
||||
\begin{frame}{Mi a HTTP?}
|
||||
\footnotesize
|
||||
Amikor a böngésződ betölt egy weboldalt, vagy amikor egy mobilalkalmazás adatot kér egy szervertől, a háttérben szinte mindig a \textbf{HTTP} (HyperText Transfer Protocol) protokoll zajlik. Ez egy egyszerű, szövegalapú szabályrendszer arra, hogyan kérjen adatot egy kliens (pl. böngésző) egy szervertől, és hogyan válaszoljon arra a szerver.
|
||||
|
||||
\begin{itemize}
|
||||
\item Kliens-szerver kommunikáció alapja a weben
|
||||
\item \textbf{Állapotmentes (stateless)} protokoll: a szerver alapból nem emlékszik az előző kérésekre -- minden kérés önmagában, a többitől függetlenül értelmezhető
|
||||
\item \textbf{Request-Response} modell: a kliens kér, a szerver válaszol
|
||||
\item Alapértelmezett port: 80 (HTTP), 443 (HTTPS)
|
||||
\end{itemize}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}{HTTP verziók}
|
||||
\footnotesize
|
||||
A HTTP protokoll az évek során több jelentős verzióváltáson esett át, mindig azzal a céllal, hogy gyorsabbá és hatékonyabbá tegye a weben zajló kommunikációt. Ma leggyakrabban HTTP/1.1-gyel és HTTP/2-vel találkozunk, de egyre több nagy szolgáltatás áll át a legújabb HTTP/3-ra is.
|
||||
|
||||
\begin{block}{}
|
||||
\begin{itemize}
|
||||
\item \textbf{HTTP/1.1} (1997) -- perzisztens kapcsolat, azaz nem kell minden kéréshez új TCP-kapcsolatot nyitni
|
||||
\item \textbf{HTTP/2} (2015) -- multiplexing (több kérés egyszerre, egy kapcsolaton), bináris protokoll
|
||||
\item \textbf{HTTP/3} (2022) -- a QUIC protokollra épül, UDP alapú, még gyorsabb kapcsolatfelépítés
|
||||
\end{itemize}
|
||||
\end{block}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}{HTTP vs HTTPS}
|
||||
\footnotesize
|
||||
A sima HTTP-n keresztül küldött adatokat bárki, aki hozzáfér a hálózati forgalomhoz (pl. egy nyílt wifin), el tudja olvasni, sőt módosítani is. A \textbf{HTTPS} ezt a problémát oldja meg azzal, hogy a HTTP forgalmat egy titkosítási réteg (SSL/TLS) fölé csomagolja.
|
||||
|
||||
\begin{columns}
|
||||
\begin{column}{0.48\textwidth}
|
||||
\begin{block}{HTTP}
|
||||
\begin{itemize}
|
||||
\item Titkosítatlan kommunikáció
|
||||
\item Lehallgatható, módosítható (Man-in-the-Middle támadás)
|
||||
\item Port 80
|
||||
\end{itemize}
|
||||
\end{block}
|
||||
\end{column}
|
||||
\begin{column}{0.48\textwidth}
|
||||
\begin{block}{HTTPS = HTTP + SSL/TLS}
|
||||
\begin{itemize}
|
||||
\item Titkosított kommunikáció
|
||||
\item SSL/TLS tanúsítvány szükséges hozzá
|
||||
\item Port 443
|
||||
\end{itemize}
|
||||
\end{block}
|
||||
\end{column}
|
||||
\end{columns}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}{Miért kötelező ma a HTTPS?}
|
||||
\footnotesize
|
||||
Régebben csak a bejelentkezős, kényes adatokat kezelő oldalak használtak HTTPS-t, ma viszont gyakorlatilag minden weboldalnak ezt kellene tennie -- több okból is.
|
||||
|
||||
\begin{alertblock}{Fontos}
|
||||
Modern webalkalmazásoknál a HTTPS gyakorlatilag kötelező: a böngészők figyelmeztetést adnak a sima HTTP oldalakra, a keresőmotorok (SEO) hátrébb sorolják őket, és sok modern böngésző-funkció (pl. helymeghatározás, kamera) is csak HTTPS mellett engedélyezett.
|
||||
\end{alertblock}
|
||||
|
||||
\begin{itemize}
|
||||
\item \textbf{Bizalom:} a felhasználó látja a lakat ikont, tudja, hogy az adatai védve utaznak
|
||||
\item \textbf{Integritás:} útközben senki nem tudja módosítani a forgalmat (pl. reklámot beszúrni)
|
||||
\item \textbf{Hitelesség:} a tanúsítvány igazolja, hogy tényleg azzal a szerverrel beszélünk, akivel hisszük
|
||||
\end{itemize}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}{HTTP metódusok}
|
||||
\footnotesize
|
||||
Minden HTTP kérésnek van egy \textbf{metódusa}, ami megmondja, milyen műveletet szeretnénk végrehajtani az adott erőforráson. A REST API-k tervezésénél ez a metódusválasztás lesz az egyik legfontosabb döntésünk.
|
||||
|
||||
\begin{tabular}{|l|p{7cm}|}
|
||||
\hline
|
||||
\textbf{Metódus} & \textbf{Jelentés} \\
|
||||
\hline
|
||||
GET & Erőforrás lekérése (csak olvasás, idempotens) \\
|
||||
POST & Új erőforrás létrehozása (nem idempotens) \\
|
||||
PUT & Erőforrás teljes frissítése (idempotens) \\
|
||||
PATCH & Erőforrás részleges frissítése (nem idempotens) \\
|
||||
DELETE & Erőforrás törlése (idempotens) \\
|
||||
HEAD & Mint GET, de csak fejlécek, body nélkül \\
|
||||
OPTIONS & Támogatott metódusok lekérése (CORS) \\
|
||||
\hline
|
||||
\end{tabular}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}{Idempotencia -- miért számít?}
|
||||
\footnotesize
|
||||
Egy művelet \textbf{idempotens}, ha többszöri végrehajtása ugyanazt az eredményt adja, mint az egyszeri. Ennek nagy jelentősége van a gyakorlatban: ha egy kérés elakad a hálózaton és a kliens újraküldi, idempotens metódusnál (GET, PUT, DELETE) nem történik semmi baj -- a végállapot ugyanaz marad.
|
||||
|
||||
\begin{block}{Példa}
|
||||
Ha kétszer küldöd el ugyanazt a \texttt{DELETE /api/users/123} kérést, a felhasználó csak egyszer törlődik -- a második kérés egyszerűen nem talál már semmit, amit törölnie kellene.
|
||||
\end{block}
|
||||
|
||||
\begin{alertblock}{POST nem idempotens}
|
||||
Ha egy \texttt{POST}-tal új erőforrást hozunk létre, és véletlenül kétszer küldjük el (pl. dupla kattintás egy "Rendelés leadása" gombon), két különálló erőforrás (pl. két rendelés) jöhet létre!
|
||||
\end{alertblock}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}[fragile]{HTTP Request felépítése}
|
||||
\footnotesize
|
||||
Egy HTTP kérés mindig ugyanabból a három részből épül fel: egy sorból, ami leírja, mit kérünk, néhány fejlécből, és opcionálisan egy törzsből (body).
|
||||
|
||||
\begin{block}{Request struktúra}
|
||||
\begin{verbatim}
|
||||
GET /api/users/123 HTTP/1.1
|
||||
Host: example.com
|
||||
Accept: application/json
|
||||
Authorization: Bearer token123
|
||||
\end{verbatim}
|
||||
\end{block}
|
||||
|
||||
\begin{itemize}
|
||||
\item \textbf{Request Line:} metódus (GET), útvonal (\texttt{/api/users/123}), protokoll verzió
|
||||
\item \textbf{Headers:} metaadatok kulcs-érték párok formájában (pl. milyen formátumot fogadunk el, kik vagyunk)
|
||||
\item \textbf{Body:} opcionális adatok, jellemzően POST, PUT, PATCH kéréseknél (pl. egy új felhasználó adatai JSON-ban)
|
||||
\end{itemize}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}[fragile]{HTTP Response felépítése}
|
||||
\footnotesize
|
||||
A szerver válasza (response) hasonló szerkezetű, csak itt a kérés helyett egy \textbf{státuszkód} mondja meg, hogy sikerült-e a kérés.
|
||||
|
||||
\begin{block}{Response struktúra}
|
||||
\begin{verbatim}
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: application/json
|
||||
|
||||
{"id": 123, "name": "Alice"}
|
||||
\end{verbatim}
|
||||
\end{block}
|
||||
|
||||
\begin{itemize}
|
||||
\item \textbf{Status Line:} protokoll, státuszkód (200), státusz szöveg (OK)
|
||||
\item \textbf{Headers:} metaadatok (pl. milyen formátumú a válasz törzse)
|
||||
\item \textbf{Body:} a válasz tényleges tartalma (HTML, JSON, XML, stb.)
|
||||
\end{itemize}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}{HTTP státuszkódok}
|
||||
\footnotesize
|
||||
A státuszkód egy háromjegyű szám, aminek az \emph{első számjegye} határozza meg a kategóriáját. Nem kell mind a száznál is több kódot fejből tudni -- elég, ha felismered, melyik kategóriába tartozik egy adott kód.
|
||||
|
||||
\begin{itemize}
|
||||
\item \textbf{1xx -- Informational:} ritkán találkozunk vele, ideiglenes válasz (pl. 101 Switching Protocols)
|
||||
\item \textbf{2xx -- Success:} a kérés sikeres volt (200 OK, 201 Created, 204 No Content)
|
||||
\item \textbf{3xx -- Redirection:} a kliensnek egy másik URL-re kell mennie (301 Moved Permanently, 302 Found, 304 Not Modified)
|
||||
\item \textbf{4xx -- Client Error:} a kliens hibázott (400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found, 429 Too Many Requests)
|
||||
\item \textbf{5xx -- Server Error:} a szerver oldalán történt hiba, a kliens kérése önmagában helyes volt (500 Internal Server Error, 502 Bad Gateway, 503 Service Unavailable)
|
||||
\end{itemize}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}{REST API-ban gyakori státuszkódok}
|
||||
\footnotesize
|
||||
Egy jól megtervezett REST API mindig következetesen használja a státuszkódokat -- ez az egyik legfontosabb szokás, amit már most érdemes elsajátítani, hiszen a következő heteken folyamatosan ezekkel fogunk dolgozni.
|
||||
|
||||
\begin{tabular}{|l|l|l|}
|
||||
\hline
|
||||
\textbf{Metódus} & \textbf{Sikeres} & \textbf{Hiba} \\
|
||||
\hline
|
||||
GET & 200 OK & 404 Not Found \\
|
||||
POST & 201 Created & 400, 409 Conflict \\
|
||||
PUT & 200 OK / 204 No Content & 400, 404 Not Found \\
|
||||
PATCH & 200 OK & 400, 404 Not Found \\
|
||||
DELETE & 204 No Content & 404 Not Found \\
|
||||
\hline
|
||||
\end{tabular}
|
||||
|
||||
\begin{block}{Két gyakori, metódusfüggetlen eset}
|
||||
Autentikáció: 401 Unauthorized (nincs bejelentkezve), 403 Forbidden (be van jelentkezve, de nincs jogosultsága) \\
|
||||
Szerver hiba: 500 Internal Server Error, 503 Service Unavailable
|
||||
\end{block}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}{HTTPS -- SSL/TLS Handshake}
|
||||
\footnotesize
|
||||
Mielőtt egy HTTPS kapcsolaton bármilyen adat átmenne, a kliens és a szerver egy rövid "kézfogáson" (handshake) esik át, aminek célja, hogy közösen kialakítsanak egy titkos kulcsot, amit csak ők ketten ismernek.
|
||||
|
||||
\begin{enumerate}
|
||||
\item \textbf{Client Hello} -- a kliens elküldi, milyen titkosítási módokat támogat
|
||||
\item \textbf{Server Hello} -- a szerver kiválasztja a közösen támogatott titkosítást, és elküldi a tanúsítványát
|
||||
\item \textbf{Certificate Verify} -- a kliens ellenőrzi a tanúsítványt egy megbízható hitelesítésszolgáltatónál (CA)
|
||||
\item \textbf{Key Exchange} -- létrejön egy közös, szimmetrikus titkosító kulcs
|
||||
\item \textbf{Finished} -- innentől minden adat ezzel a kulccsal titkosítva utazik
|
||||
\end{enumerate}
|
||||
|
||||
\begin{block}{SSL/TLS verziók}
|
||||
A TLS 1.2 még sok helyen használatban van, de a TLS 1.3 az ajánlott: gyorsabb kapcsolatfelépítés és erősebb, biztonságosabb titkosítási módok.
|
||||
\end{block}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}{Összefoglalás -- HTTP/HTTPS}
|
||||
\footnotesize
|
||||
\begin{block}{HTTP/HTTPS alapok}
|
||||
\begin{itemize}
|
||||
\item HTTP: Request-Response modell, állapotmentes (stateless) protokoll
|
||||
\item HTTPS: titkosított HTTP, SSL/TLS handshake-kel
|
||||
\item HTTP metódusok: GET, POST, PUT, PATCH, DELETE -- mindegyiknek megvan a maga szerepe
|
||||
\item Idempotencia: GET, PUT, DELETE biztonságosan újraküldhető
|
||||
\item Státuszkódok: az első számjegy adja meg a kategóriát (1xx--5xx)
|
||||
\item REST API-ban leggyakrabban használt kódok: 200, 201, 204, 400, 401, 403, 404, 500
|
||||
\end{itemize}
|
||||
\end{block}
|
||||
\end{frame}
|
||||
@@ -0,0 +1,196 @@
|
||||
\section{Node.js Alapok}
|
||||
|
||||
\begin{frame}{Mi a Node.js?}
|
||||
\footnotesize
|
||||
A Javascript eredetileg kizárólag böngészőkben futott. A \textbf{Node.js} ezt változtatta meg: kiszedte a Google Chrome V8 motorját a böngészőből, és lehetővé tette, hogy Javascript kód a szerveren, önállóan is fusson -- így írhatunk vele backend alkalmazásokat, parancssori eszközöket, akár build-rendszereket is.
|
||||
|
||||
\begin{itemize}
|
||||
\item JavaScript futtatókörnyezet a V8 motoron alapulva
|
||||
\item Szerveroldali JavaScript fejlesztés lehetősége
|
||||
\item Eseményvezérelt, nem blokkoló (non-blocking) I/O modell
|
||||
\item Létrehozta: Ryan Dahl (2009)
|
||||
\end{itemize}
|
||||
|
||||
\begin{block}{Miért Node.js?}
|
||||
Ugyanazt a nyelvet használhatjuk frontend és backend oldalon is, hatalmas npm ökoszisztéma áll rendelkezésre szinte bármilyen problémára, és gyors vele a fejlesztés, prototípuskészítés.
|
||||
\end{block}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}{Node.js architektúra}
|
||||
\footnotesize
|
||||
A Node.js két fő komponensre épül: a Javascript kódot lefordító és futtató \textbf{V8 motorra}, valamint a háttérben futó \textbf{libuv} könyvtárra, ami az aszinkron I/O műveleteket (fájl, hálózat) kezeli.
|
||||
|
||||
\begin{columns}
|
||||
\begin{column}{0.48\textwidth}
|
||||
\begin{block}{V8 JavaScript Engine}
|
||||
\begin{itemize}
|
||||
\item Google Chrome motorja
|
||||
\item JIT (Just-In-Time) fordítás
|
||||
\item C++ nyelven íródott, rendkívül gyors
|
||||
\end{itemize}
|
||||
\end{block}
|
||||
\end{column}
|
||||
\begin{column}{0.48\textwidth}
|
||||
\begin{block}{libuv}
|
||||
\begin{itemize}
|
||||
\item Event loop implementáció
|
||||
\item Aszinkron I/O műveletek
|
||||
\item Cross-platform támogatás
|
||||
\end{itemize}
|
||||
\end{block}
|
||||
\end{column}
|
||||
\end{columns}
|
||||
|
||||
\begin{alertblock}{Event Loop}
|
||||
Timers $\to$ Pending callbacks $\to$ Poll (I/O) $\to$ Check $\to$ Close callbacks. A Node.js egyetlen szálon (single-threaded) fut, de az I/O műveletek aszinkron módon, a háttérben zajlanak -- így egy lassú fájlművelet nem blokkolja a többi kérés kiszolgálását.
|
||||
\end{alertblock}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}[fragile]{Első Node.js program}
|
||||
\footnotesize
|
||||
Nézzünk egy egyszerű, de tanulságos első programot, ami megmutatja, milyen beépített, Node.js-specifikus változókhoz férünk hozzá.
|
||||
|
||||
\begin{block}{hello.js -- futtatás: \texttt{node hello.js}}
|
||||
\begin{lstlisting}[language=JavaScript,style=NodeJS]
|
||||
console.log('Hello, Node.js!');
|
||||
console.log('Node verzio:', process.version);
|
||||
console.log('Aktualis konyvtar:', __dirname);
|
||||
\end{lstlisting}
|
||||
\end{block}
|
||||
|
||||
\begin{alertblock}{Fontos}
|
||||
A Node.js nem böngésző! Nincs \texttt{window}, nincs \texttt{document}, de van helyette \texttt{global} (a böngésző \texttt{window}-jának megfelelője) és \texttt{process} (a futó Node.js folyamatról ad információt).
|
||||
\end{alertblock}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}[fragile]{Modulrendszer -- CommonJS}
|
||||
\footnotesize
|
||||
Ahogy a kódunk növekszik, elkerülhetetlen, hogy több fájlra bontsuk. A Node.js hagyományos, alapértelmezett modulrendszere a \textbf{CommonJS}, ahol a \texttt{require} és a \texttt{module.exports} párossal osztunk meg kódot fájlok között.
|
||||
|
||||
\begin{columns}
|
||||
\begin{column}{0.48\textwidth}
|
||||
\begin{block}{math.js -- export}
|
||||
\begin{lstlisting}[language=JavaScript,style=NodeJS]
|
||||
function add(a, b) {
|
||||
return a + b;
|
||||
}
|
||||
module.exports = { add };
|
||||
\end{lstlisting}
|
||||
\end{block}
|
||||
\end{column}
|
||||
\begin{column}{0.48\textwidth}
|
||||
\begin{block}{app.js -- import}
|
||||
\begin{lstlisting}[language=JavaScript,style=NodeJS]
|
||||
const math = require('./math');
|
||||
console.log(math.add(2, 3));
|
||||
// 5
|
||||
\end{lstlisting}
|
||||
\end{block}
|
||||
\end{column}
|
||||
\end{columns}
|
||||
|
||||
\begin{block}{Beépített (core) modulok}
|
||||
A Node.js számos hasznos modult ad eleve a kezünkbe, telepítés nélkül: \texttt{fs} (file system, fájlkezelés), \texttt{path} (útvonalak kezelése), \texttt{http} (webszerver készítése).
|
||||
\end{block}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}[fragile]{ES Modules (ESM)}
|
||||
\footnotesize
|
||||
A modern Javascript szabvány, az ECMAScript saját, egységes modulrendszert vezetett be \texttt{import}/\texttt{export} kulcsszavakkal -- ugyanezt ismerheted a frontend keretrendszerekből (React, Vue) is. A Node.js is támogatja ezt, ha bekapcsoljuk.
|
||||
|
||||
\begin{columns}
|
||||
\begin{column}{0.48\textwidth}
|
||||
\begin{block}{math.mjs -- export}
|
||||
\begin{lstlisting}[language=JavaScript,style=NodeJS]
|
||||
export function add(a, b) {
|
||||
return a + b;
|
||||
}
|
||||
\end{lstlisting}
|
||||
\end{block}
|
||||
\end{column}
|
||||
\begin{column}{0.48\textwidth}
|
||||
\begin{block}{app.mjs -- import}
|
||||
\begin{lstlisting}[language=JavaScript,style=NodeJS]
|
||||
import { add } from './math.mjs';
|
||||
console.log(add(2, 3));
|
||||
\end{lstlisting}
|
||||
\end{block}
|
||||
\end{column}
|
||||
\end{columns}
|
||||
|
||||
\begin{alertblock}{package.json}
|
||||
Az ESM használatához be kell állítani: \texttt{\{"type": "module"\}} a \texttt{package.json} fájlban -- ekkor a \texttt{.js} kiterjesztésű fájlok is ES modulként fognak viselkedni.
|
||||
\end{alertblock}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}[fragile]{File System műveletek}
|
||||
\footnotesize
|
||||
A backend fejlesztés egyik leggyakoribb feladata fájlokkal dolgozni (konfiguráció olvasása, log írása, feltöltött fájlok kezelése). A Node.js \texttt{fs} modulja ehhez háromféle API-t is kínál.
|
||||
|
||||
\begin{block}{Fájl olvasás -- Promise API (ajánlott)}
|
||||
\begin{lstlisting}[language=JavaScript,style=NodeJS]
|
||||
const fs = require('fs').promises;
|
||||
|
||||
async function readData() {
|
||||
const data = await fs.readFile('input.txt', 'utf8');
|
||||
console.log(data);
|
||||
}
|
||||
\end{lstlisting}
|
||||
\end{block}
|
||||
|
||||
\begin{itemize}
|
||||
\item \texttt{readFileSync} -- szinkron, blokkolja a végrehajtást, amíg be nem fejeződik (kerülendő szerveroldalon)
|
||||
\item \texttt{readFile} callback-kel -- aszinkron, a régebbi, callback-alapú stílus
|
||||
\item \texttt{fs.promises} -- aszinkron, \texttt{async/await}-tel szépen, szinkron kódként olvasható -- ma ez az ajánlott megoldás
|
||||
\end{itemize}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}[fragile]{HTTP szerver létrehozása}
|
||||
\footnotesize
|
||||
Ahogy korábban láttuk, a HTTP request-response modellt bármilyen nyelven meg lehet valósítani. Node.js-ben a beépített \texttt{http} modullal mindössze néhány sorból már működő webszervert tudunk indítani -- ez az alapja mindannak, amit a következő heteken Express.js-szel fogunk csinálni.
|
||||
|
||||
\begin{block}{Egyszerű HTTP szerver}
|
||||
\begin{lstlisting}[language=JavaScript,style=NodeJS]
|
||||
const http = require('http');
|
||||
const server = http.createServer((req, res) => {
|
||||
res.statusCode = 200;
|
||||
res.setHeader('Content-Type', 'text/plain');
|
||||
res.end('Hello, Node.js szerver!\n');
|
||||
});
|
||||
server.listen(3000, () => {
|
||||
console.log('Szerver fut: http://localhost:3000');
|
||||
});
|
||||
\end{lstlisting}
|
||||
\end{block}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}{Node.js vs. Böngésző}
|
||||
\footnotesize
|
||||
Fontos tudatosítani, hogy bár mindkét környezetben Javascript kód fut, a Node.js és a böngésző \emph{teljesen más} környezetet biztosítanak -- más API-k érhetők el, és más a rendeltetésük is.
|
||||
|
||||
\begin{tabular}{|l|l|l|}
|
||||
\hline
|
||||
\textbf{Jellemző} & \textbf{Node.js} & \textbf{Böngésző} \\
|
||||
\hline
|
||||
DOM API & Nincs & Van \\
|
||||
\texttt{window} objektum & Nincs & Van \\
|
||||
Globális objektum & \texttt{global} & \texttt{window} \\
|
||||
File system & Van (\texttt{fs}) & Nincs \\
|
||||
HTTP szerver & Készíthető & Nem \\
|
||||
Használat & Backend, CLI & Frontend \\
|
||||
\hline
|
||||
\end{tabular}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}{Összefoglalás -- Node.js}
|
||||
\footnotesize
|
||||
\begin{block}{Node.js alapok}
|
||||
\begin{itemize}
|
||||
\item V8 engine alapú JavaScript futtatókörnyezet, szerveroldalon
|
||||
\item Event-driven, non-blocking I/O modell -- egy szálon, de aszinkron módon
|
||||
\item Modulrendszer: CommonJS (\texttt{require}) és ES Modules (\texttt{import})
|
||||
\item Beépített modulok: \texttt{fs} (fájlok), \texttt{path} (útvonalak), \texttt{http} (szerver)
|
||||
\item HTTP szerver készítése pár sorban -- ez az alapja a jövő heti Express.js-nek
|
||||
\end{itemize}
|
||||
\end{block}
|
||||
\end{frame}
|
||||
@@ -0,0 +1,253 @@
|
||||
\section{NPM Package Manager}
|
||||
|
||||
\begin{frame}[fragile]{Mi az npm?}
|
||||
\footnotesize
|
||||
Amint elkezdünk egy valós projekten dolgozni, hamar szükségünk lesz mások által megírt kódra -- ne írjunk újra mindent nulláról! Az \textbf{npm} (Node Package Manager) ebben segít: ez a Node.js hivatalos csomagkezelője, amivel telepíthetünk, frissíthetünk és megoszthatunk kódcsomagokat.
|
||||
|
||||
\begin{itemize}
|
||||
\item Node Package Manager -- Node.js csomagkezelője
|
||||
\item A világ legnagyobb szoftver registry-je (2+ millió csomag)
|
||||
\item Node.js-szel együtt települ, külön telepíteni nem kell
|
||||
\item Projekt függőségek kezelése, verziószám ellenőrzése
|
||||
\end{itemize}
|
||||
|
||||
\begin{block}{Verziószám ellenőrzése}
|
||||
\begin{verbatim}
|
||||
node --version
|
||||
npm --version
|
||||
\end{verbatim}
|
||||
\end{block}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}[fragile]{npm alternatívái}
|
||||
\footnotesize
|
||||
Bár a tárgy során mindvégig az npm-et fogjuk használni, érdemes tudni, hogy nem ez az egyetlen csomagkezelő a Node.js ökoszisztémában -- a szakmában több helyen találkozhatsz az alternatíváival is.
|
||||
|
||||
\begin{alertblock}{Alternatívák}
|
||||
\texttt{yarn} és \texttt{pnpm} -- ugyanazt a célt szolgálják, mint az npm, csak némileg gyorsabbak és hatékonyabbak lehetnek nagyobb projekteknél. A \texttt{pnpm} például egyetlen, megosztott tárolóban tartja a csomagokat, így lemezterületet spórol.
|
||||
\end{alertblock}
|
||||
|
||||
A parancsok szinte megegyeznek egymással (\texttt{npm install} $\leftrightarrow$ \texttt{yarn add} $\leftrightarrow$ \texttt{pnpm add}), így ha megtanulod az egyiket, a többit is könnyen felveszed majd.
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}[fragile]{npm init -- Projekt inicializálás}
|
||||
\footnotesize
|
||||
Minden Node.js projekt egy \texttt{package.json} fájllal kezdődik, ami leírja a projekt metaadatait (nevét, verzióját, függőségeit). Ezt a fájlt az \texttt{npm init} parancs generálja le nekünk.
|
||||
|
||||
\begin{block}{Interaktív projekt létrehozás}
|
||||
\begin{verbatim}
|
||||
npm init
|
||||
\end{verbatim}
|
||||
Ekkor az npm sorra megkérdezi a projekt nevét, verzióját, leírását, stb.
|
||||
\end{block}
|
||||
|
||||
\begin{block}{Gyors inicializálás alapértelmezett értékekkel}
|
||||
\begin{verbatim}
|
||||
npm init -y
|
||||
\end{verbatim}
|
||||
\end{block}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}{npm init -- mit hoz létre?}
|
||||
\footnotesize
|
||||
Mindkét változat ugyanazt az egy fájlt hozza létre -- csak abban különböznek, hogy megkérdezik-e tőlünk előtte a projekt adatait, vagy rögtön alapértelmezett értékekkel dolgoznak.
|
||||
|
||||
\begin{alertblock}{Eredmény}
|
||||
Létrejön a \texttt{package.json} fájl, amely a projekt metaadatait tartalmazza, és ami a projektünk "személyi igazolványaként" működik: ebben tároljuk a nevét, verzióját, a függőségeit és a saját parancsainkat is.
|
||||
\end{alertblock}
|
||||
|
||||
Ha egy projektet klónozol githubról, az első dolgod mindig az legyen, hogy megnézed a \texttt{package.json}-t -- ebből azonnal kiderül, milyen technológiákat használ, és hogyan indítható.
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}[fragile]{package.json struktúra}
|
||||
\footnotesize
|
||||
Érdemes megismerkedni a \texttt{package.json} legfontosabb mezőivel, hiszen ez a fájl fogja a félév során minden projektünket összefogni.
|
||||
|
||||
\begin{lstlisting}[language=JavaScript,style=NodeJS]
|
||||
{
|
||||
"name": "backend-app",
|
||||
"version": "1.0.0",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"start": "node index.js",
|
||||
"dev": "nodemon index.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"express": "^4.18.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"nodemon": "^3.0.1"
|
||||
}
|
||||
}
|
||||
\end{lstlisting}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}{package.json mezői}
|
||||
\footnotesize
|
||||
A \texttt{scripts} mező alatt saját parancsainkat definiálhatjuk, a \texttt{dependencies} és \texttt{devDependencies} pedig a projekt függőségeit sorolja fel.
|
||||
|
||||
\begin{itemize}
|
||||
\item \texttt{name}, \texttt{version} -- a projekt azonosítója és verziója
|
||||
\item \texttt{main} -- melyik fájl a belépési pont, ha valaki \texttt{require}-olja a projektünket
|
||||
\item \texttt{scripts} -- rövid parancsok gyakori feladatokra (erről bővebben pár dia múlva)
|
||||
\item \texttt{dependencies} / \texttt{devDependencies} -- a projekt függőségei (erről is bővebben mindjárt)
|
||||
\end{itemize}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}[fragile]{Csomagok telepítése -- production függőségek}
|
||||
\footnotesize
|
||||
Amikor egy csomagra van szükségünk, az \texttt{npm install} (röviden \texttt{npm i}) paranccsal tudjuk hozzáadni a projekthez. Fontos eldönteni, hogy a csomagra csak fejlesztés közben, vagy éles működéskor is szükség lesz-e.
|
||||
|
||||
\begin{block}{Production függőségként}
|
||||
\begin{verbatim}
|
||||
npm install express
|
||||
npm i express
|
||||
\end{verbatim}
|
||||
\end{block}
|
||||
|
||||
Ezek a csomagok a \texttt{dependencies} alá kerülnek a \texttt{package.json}-ben -- ezek nélkül az alkalmazásunk éles környezetben sem tudna elindulni, hiszen a kódunk ténylegesen használja őket futás közben (pl. az Express.js keretrendszert magát).
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}[fragile]{Csomagok telepítése -- development függőségek}
|
||||
\footnotesize
|
||||
Vannak olyan eszközök, amikre csak a fejlesztés közben van szükségünk (pl. automatikus újraindítás, tesztelés, kódformázás) -- ezeket nem érdemes az éles szerverre is felmásolni.
|
||||
|
||||
\begin{block}{Development függőségként}
|
||||
\begin{verbatim}
|
||||
npm install --save-dev nodemon
|
||||
npm i -D nodemon jest eslint
|
||||
\end{verbatim}
|
||||
\end{block}
|
||||
|
||||
\begin{alertblock}{Mi a különbség?}
|
||||
\texttt{dependencies}: éles környezetben is kell \quad|\quad \texttt{devDependencies}: csak fejlesztéshez (pl. tesztelő, formázó eszközök)
|
||||
\end{alertblock}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}{Semantic Versioning (SemVer)}
|
||||
\footnotesize
|
||||
Az npm csomagok verziószámozása egy szigorú, háromrészes konvenciót követ, amiből azonnal leolvasható, hogy egy frissítés mekkora változást hozhat.
|
||||
|
||||
\begin{block}{Verzió formátum}
|
||||
\texttt{1.2.3} $\to$ \texttt{1} (major) . \texttt{2} (minor) . \texttt{3} (patch)
|
||||
\end{block}
|
||||
|
||||
\begin{itemize}
|
||||
\item \textbf{MAJOR:} nem kompatibilis, "törő" API változás
|
||||
\item \textbf{MINOR:} új funkció, de visszafelé kompatibilis
|
||||
\item \textbf{PATCH:} hibajavítás, visszafelé kompatibilis
|
||||
\end{itemize}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}{SemVer jelölések a package.json-ban}
|
||||
\footnotesize
|
||||
A \texttt{package.json}-ban a verziószám elé írt jel (\texttt{\^{}} vagy \texttt{\textasciitilde}) szabja meg, hogy \texttt{npm install}/\texttt{npm update} során milyen új verziókat fogadunk el automatikusan.
|
||||
|
||||
\begin{tabular}{|l|l|}
|
||||
\hline
|
||||
\textbf{Jelölés} & \textbf{Jelentés} \\
|
||||
\hline
|
||||
\texttt{1.2.3} & Pontosan 1.2.3 verzió \\
|
||||
\texttt{\^{}1.2.3} & $\geq$ 1.2.3 és $<$ 2.0.0 (MINOR frissítések engedélyezve) \\
|
||||
\texttt{\textasciitilde 1.2.3} & $\geq$ 1.2.3 és $<$ 1.3.0 (csak PATCH frissítések) \\
|
||||
\texttt{latest} & Mindig a legfrissebb verzió \\
|
||||
\hline
|
||||
\end{tabular}
|
||||
|
||||
\begin{alertblock}{Gyakori alapértelmezés}
|
||||
Az \texttt{npm install csomagnev} alapból a \texttt{\^{}} jelölést használja -- ez a leggyakoribb, kényelmes középút a stabilitás és a frissesség között.
|
||||
\end{alertblock}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}[fragile]{npm scripts}
|
||||
\footnotesize
|
||||
A \texttt{package.json} \texttt{scripts} mezőjében saját, rövid parancsokat definiálhatunk a gyakran ismételt feladatokra (indítás, tesztelés, linting) -- így nem kell mindig hosszú parancsokat begépelni.
|
||||
|
||||
\begin{lstlisting}[language=JavaScript,style=NodeJS]
|
||||
{
|
||||
"scripts": {
|
||||
"start": "node index.js",
|
||||
"dev": "nodemon index.js",
|
||||
"test": "jest",
|
||||
"lint": "eslint ."
|
||||
}
|
||||
}
|
||||
\end{lstlisting}
|
||||
|
||||
\begin{block}{Scripts futtatása}
|
||||
\begin{verbatim}
|
||||
npm run dev
|
||||
npm start # 'run' nelkul is mukodik
|
||||
\end{verbatim}
|
||||
\end{block}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}{node\_modules és package-lock.json}
|
||||
\footnotesize
|
||||
Amikor telepítünk egy csomagot, az npm két dolgot hoz létre: egy \texttt{node\_modules} mappát a tényleges kóddal, és egy \texttt{package-lock.json} fájlt. Fontos tudni, melyiket kell git-ben verziókövetni, és melyiket nem.
|
||||
|
||||
\begin{columns}
|
||||
\begin{column}{0.48\textwidth}
|
||||
\begin{block}{node\_modules}
|
||||
\begin{itemize}
|
||||
\item A telepített csomagok tényleges kódját tartalmazó mappa
|
||||
\item Nagyon nagy tud lenni (akár több száz MB)
|
||||
\item Ne commitoljuk git-be!
|
||||
\item Újragenerálás: \texttt{npm install}
|
||||
\end{itemize}
|
||||
\end{block}
|
||||
\end{column}
|
||||
\begin{column}{0.48\textwidth}
|
||||
\begin{block}{package-lock.json}
|
||||
\begin{itemize}
|
||||
\item Pontosan rögzíti, melyik csomagból melyik verzió lett telepítve
|
||||
\item Determinisztikus, mindenkinél ugyanazt eredményező telepítést biztosít
|
||||
\item Ezt viszont commitoljuk git-be!
|
||||
\end{itemize}
|
||||
\end{block}
|
||||
\end{column}
|
||||
\end{columns}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}[fragile]{Hasznos npm parancsok és npx}
|
||||
\footnotesize
|
||||
Néhány további parancs, amire a mindennapi munka során gyakran szükség lesz: a projekt állapotának ellenőrzésére, illetve arra, hogy egy csomagot telepítés nélkül, egyszer futtassunk le.
|
||||
|
||||
\begin{columns}
|
||||
\begin{column}{0.48\textwidth}
|
||||
\begin{block}{Karbantartás}
|
||||
\begin{verbatim}
|
||||
npm list
|
||||
npm outdated
|
||||
npm audit
|
||||
npm audit fix
|
||||
\end{verbatim}
|
||||
\end{block}
|
||||
\end{column}
|
||||
\begin{column}{0.48\textwidth}
|
||||
\begin{block}{npx -- futtatás telepítés nélkül}
|
||||
\begin{verbatim}
|
||||
npx prisma init
|
||||
npx tsx index.ts
|
||||
\end{verbatim}
|
||||
\end{block}
|
||||
\end{column}
|
||||
\end{columns}
|
||||
|
||||
Az \texttt{npx} egy segédeszközt csak egyszer, ideiglenesen tölt le és futtat le, anélkül, hogy állandó jelleggel telepítené a gépünkre.
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}{Összefoglalás -- NPM}
|
||||
\footnotesize
|
||||
\begin{block}{npm alapok}
|
||||
\begin{itemize}
|
||||
\item npm: Node Package Manager, 2+ millió elérhető csomag
|
||||
\item \texttt{npm init} -- projekt inicializálása, \texttt{package.json} létrehozása
|
||||
\item \texttt{npm install/uninstall/update} -- csomagkezelés
|
||||
\item \texttt{dependencies} vs \texttt{devDependencies} -- éles vs csak fejlesztői függőség
|
||||
\item Semantic Versioning: \texttt{MAJOR.MINOR.PATCH}
|
||||
\item \texttt{node\_modules} (ne commitold), \texttt{package-lock.json} (ezt viszont igen)
|
||||
\item \texttt{npx}: csomagok egyszeri futtatása telepítés nélkül
|
||||
\end{itemize}
|
||||
\end{block}
|
||||
\end{frame}
|
||||
@@ -0,0 +1,13 @@
|
||||
\section{Következő lépések}
|
||||
|
||||
\begin{frame}{Következő lépések}
|
||||
\footnotesize
|
||||
A mai órán megismertük a webes kommunikáció alapjait, elindítottunk egy Node.js szervert, és megtanultuk, hogyan kezeljük a projekt függőségeit npm-mel. A következő alkalomig érdemes ezeket a lépéseket elvégezni:
|
||||
|
||||
\begin{enumerate}
|
||||
\item \textbf{Fejlesztői környezet telepítése} (Node.js, npm) -- ha még nincs telepítve, mindenképp pótold otthon
|
||||
\item \textbf{Git és verziókezelés alapjai} -- a kódunkat innentől mindig verziókezelve fogjuk fejleszteni
|
||||
\item \textbf{Első Express.js alkalmazás elkészítése} -- a jövő héten a beépített \texttt{http} modul helyett egy sokkal kényelmesebb keretrendszert használunk
|
||||
\item \textbf{REST API alapok megismerése} (2. hét) -- ráépítünk a mai HTTP-s tudásra
|
||||
\end{enumerate}
|
||||
\end{frame}
|
||||
Reference in new issue
Block a user