\section{Routing} \begin{frame}[fragile]{HTTP metódusok Express-ben} \footnotesize Minden HTTP metódushoz külön Express függvény tartozik, ami pontosan a metódus nevét viseli -- ez sokkal olvashatóbb, mint egy \texttt{if (req.method === ...)} lánc. \begin{lstlisting}[language=JavaScript,style=NodeJS] app.get('/users', (req, res) => { /* lista */ }); app.post('/users', (req, res) => { /* letrehozas */ }); app.get('/users/:id', (req, res) => { /* egy elem */ }); app.put('/users/:id', (req, res) => { /* teljes frissites */ }); app.patch('/users/:id', (req, res) => { /* reszleges frissites */ }); app.delete('/users/:id', (req, res) => { /* torles */ }); \end{lstlisting} \begin{block}{Emlékeztető} Ez pontosan a 2. héten (a jövő héten, amikor visszatérünk rá) tárgyalt CRUD $\to$ HTTP metódus táblázatot követi -- nem véletlen az egyezés. \end{block} \end{frame} \begin{frame}[fragile]{Route paraméterek és query stringek} \footnotesize Az útvonalban lévő \texttt{:id}-hez hasonló szegmenseket \textbf{route paramétereknek} hívjuk, a kérdőjel utáni \texttt{?key=value} részt pedig \textbf{query stringnek}. Express mindkettőt készen, feldolgozva adja át. \begin{lstlisting}[language=JavaScript,style=NodeJS] // GET /users/123?includeOrders=true app.get('/users/:id', (req, res) => { const userId = req.params.id; // "123" const includeOrders = req.query.includeOrders; // "true" res.json({ id: userId, includeOrders }); }); \end{lstlisting} \begin{itemize} \item \textbf{\texttt{req.params}:} az útvonal része, egy konkrét erőforrás azonosítására (\texttt{/users/:id}) \item \textbf{\texttt{req.query}:} opcionális finomítás (lapozás, szűrés, rendezés) \end{itemize} \end{frame} \begin{frame}[fragile]{A kérés törzse: \texttt{req.body}} \footnotesize \texttt{POST}, \texttt{PUT} és \texttt{PATCH} kéréseknél az adat jellemzően a kérés törzsében (body) érkezik JSON formátumban -- ehhez szükséges az előző órán megismert \texttt{express.json()} middleware. \begin{lstlisting}[language=JavaScript,style=NodeJS] app.use(express.json()); app.post('/users', (req, res) => { const { name, email } = req.body; const newUser = { id: Date.now(), name, email }; users.push(newUser); res.status(201).json(newUser); }); \end{lstlisting} \begin{block}{Emlékeztető az 1. hétről} A \texttt{201 Created} a helyes státuszkód sikeres \texttt{POST} esetén -- ezt már az 1. héten megismertük. \end{block} \end{frame} \begin{frame}[fragile]{Útvonalak szervezése: \texttt{express.Router()}} \footnotesize Ahogy nő az alkalmazás, egyetlen fájlban tartani az összes route-ot áttekinthetetlenné válik. Az \texttt{express.Router()} lehetővé teszi, hogy erőforrásonként külön fájlba szervezzük az útvonalakat. \begin{columns} \begin{column}{0.48\textwidth} \begin{block}{routes/users.js} \begin{lstlisting}[language=JavaScript,style=NodeJS] const router = express.Router(); router.get('/', listUsers); router.post('/', createUser); module.exports = router; \end{lstlisting} \end{block} \end{column} \begin{column}{0.48\textwidth} \begin{block}{app.js} \begin{lstlisting}[language=JavaScript,style=NodeJS] const usersRouter = require('./routes/users'); app.use( '/users', usersRouter ); \end{lstlisting} \end{block} \end{column} \end{columns} \end{frame} \begin{frame}[fragile]{Hibakezelés alapjai} \footnotesize Express két speciális esetet kezel middleware-ekkel: amikor egy útvonal nem létezik, és amikor egy route handler hibát dob. \begin{lstlisting}[language=JavaScript,style=NodeJS] // 404 - ha semelyik route nem illeszkedett app.use((req, res) => { res.status(404).json({ error: 'Nem talalhato' }); }); // hibakezelo middleware -- negy parameter jelzi Expressnek! app.use((err, req, res, next) => { console.error(err); res.status(500).json({ error: 'Szerver hiba' }); }); \end{lstlisting} \begin{block}{Fontos} A hibakezelő middleware-t \emph{a legvégén} kell regisztrálni, az összes route után -- Express a négy paraméter alapján ismeri fel. \end{block} \end{frame} \begin{frame}{Összefoglalás -- Routing} \footnotesize \begin{block}{Routing Express-ben} \begin{itemize} \item \texttt{app.get/post/put/patch/delete} -- metódusonként külön, olvasható route definíció \item \texttt{req.params} -- útvonal paraméterek, \texttt{req.query} -- query string, \texttt{req.body} -- kérés törzse \item \texttt{express.Router()} -- útvonalak szervezése külön fájlokba, erőforrásonként \item 404 és hibakezelő middleware a route-ok végén \end{itemize} \end{block} \end{frame}