IT rekvalifikácia. Seniorní programátori zarábajú až 6 000 €/mesiac a rekvalifikácia je prvým krokom. Zisti, ako na to!

4. diel - Kompletné Restful API v Node.js

V minulej lekcii, Rozbehnutie projektu a prvé riadky v Expressu , sme si pripravili pracovné prostredie a začali sme používať knižnicu Express. Dnes v tutoriálu implementujeme kompletný Restful API v Node.js pre databázu filmov. Cestou sa naučíme používať niekoľko užitočných nástrojov.

Založenie projektu

Minule sme si pomocou NPM založili projekt a nainštalovali express. Pre dnešný aplikácii si vytvoríme nový projekt. Pre istotu si ešte raz uveďme príslušné príkazy:

mkdir node-projekt
cd node-projekt
npm init --yes
npm install express

V projekte potom ako minule do nového súboru index.js napíšeme nasledujúci kód:

const express = require('express');
const app = express();

app.listen(3000, () => console.log('Listening on port 3000...'));

Nodemon

Ak ste minule počas čítania článku písali aj kód, mohlo vás otravovať, že pri každej úprave kódu bolo treba aplikáciu reštartovať. Nástroj nodemon ponúka lepšie riešenie. Nodemon je skratka za node monitor. Stráži všetky súbory typu .js (a pár ďalších typov) v danej zložke a podpriečinkoch. Kedykoľvek sa niektorý z týchto súborov zmení, nodemon aplikáciu sám reštartuje. Všetky zmeny tak môžeme rovno vyskúšať.

Nodemon nainštalujeme opäť pomocou NPM. Väčšinou ho chceme nainštalovať globálne, s použitím parametra -g. Potom už len stačí zadať do príkazového riadku namiesto príkazu node index.js príkaz nodemon index.js:

npm install -g nodemon
nodemon index.js

Metóda GET

Metódu GET sme používali už minule. Novo bude vracať všetky filmy alebo detail jedného konkrétneho filmu. K tomu budeme samozrejme najskôr potrebovať databázu filmov.

Príprava dát

Pre začiatok nebudeme ešte používať databázu (tú si pridáme v niektorej z najbližších lekcií), ale budeme filmy držať v poli.

const movies = [
    { id: 1, name: "Kill Bill", year: 2003 },
    { id: 2, name: "Kill Bill 2", year: 2004 },
    { id: 3, name: "Star Wars IV", year: 1976 },
    { id: 4, name: "Star Wars V", year: 1980 }
];

O filmoch by sme mohli uchovávať oveľa viac dát (a v databáze tiež budeme), zatiaľ nám však postačí id, meno filmu a rok premiéry.

Implementácia metódy GET pre vás nebude ťažké, ak ste dobre čítali predchádzajúce lekciu. Prehľad ciest sme si urobili už v druhej lekcii a metódu GET už vieme:

app.get('/api/movies', (req, res) => {
    res.send(movies);
});

app.get('/api/movies/:id', (req, res) => {
    const id = Number(req.params.id);
    const movie = movies.find( movie => movie.id === id);
    if (movie) {
        res.send(movie);
    } else {
        res.status(404).send('Film nebyl nalezen.');
    }
});

V prvom volanie metódy app.get() bez parametra sa pýtame na všetky filmy, vráti sa teda celé pole. Pri druhom volaní požívame parameter id, pomocou metódy find() na vyhľadávanie v poli nájdeme správny film a vrátime ho. Ak by film neexistoval, vrátime chybovú hlášku a HTTP kód 404 Not Found (požadovaný dokument nebol nájdený).

Teraz už aplikáciu nemusíte reštartovať, stačí kód uložiť. Po zadaní http://localhost:3000/api/movies do adresného riadku sa zobrazí zoznam filmov:

Tvoja stránka
http://localhos­t:3000/api/mo­vies

Alebo môžete pridať ešte jedno lomítko a id filmu, zobrazí sa len dáta o konkrétnom filme.

Tvoja stránka
http://localhos­t:3000/api/mo­vies/1

Skúste si zadať aj id, pre ktoré film neexistuje, zobrazí sa chybová hláška (a vo vývojárskych nástrojoch pod klávesom F12 sa v paneli "Network" môžete presvedčiť, že vám server vrátil kód 404).

Node.js

Metóda POST

Určite ste si všimli, že sa pole s filmami v prehliadači nezobrazilo veľmi pekne. Prehliadač je totiž určený pre vykresľovanie webových stránok, nie pre zobrazovanie polí. Požiadavka s metódou POST by sme dokonca mali problém aj odoslať.

Postman

Preto sa hodí mať aplikáciu, ktorá nám umožní posielať všetky typy požiadaviek. Jednou takou je Postman. Stiahnite si ho z www.getpostman.com. Inštaláciu určite zvládnete sami.

Posielanie POST požiadavke na Node server v aplikácii Postman - Node.js

Po spustení zvolíme metódu GET (1), do adresného riadku napíšeme to isté čo do adresného riadku prehliadača (2), a klikneme na tlačidlo "Send" (3).

Zobrazí sa nám zoznam filmov alebo konkrétny film, podľa toho, s akou cestou sme požiadavku poslali. Okrem toho nám Postman ukazuje HTTP kód 200 OK, s ktorým odpoveď prišla (4) a mnoho ďalších informácií.

Môžete si ešte vyskúšať, že vráti kód 404 pri zadaní GET požiadavke na neexistujúce id filmu. Rovnako ako v prehliadači si v ňom môžete vytvárať záložky na rôzne požiadavky pomocou tlačidla + (5).

Od teraz už budeme všetky požiadavky na naše API posielať pomocou Postman.

Implementácia POST

Keď máme Postman, môžeme si naimplementovať metódu POST. Do index.js vložme nasledujúci kód (a súbor uložme):

app.post('/api/movies', (req, res) => {
    const movie = {
        id: movies.length + 1,
        name: req.body.name,
        year: req.body.year
    };
    movies.push(movie);
    res.send(movie);
});

Teraz voláme metódu app.post(). Požiadavka posielame na cestu bez parametra, pretože id nový film ešte nemá priradený. Teraz ho tvoríme ako dĺžku poľa plus jedna. (To nemusí byť vždy správne, ale vzhľadom k tomu, že časom to za nás bude robiť databázy, tak nám to tentokrát bude stačiť.) Potom už len pridáme film do databázy a tiež ho zobrazíme ako odpoveď (v odpovedi sa zobrazí vrátane novo vytvoreného id).

Aby kód fungoval, musíme na začiatok súboru (hneď po tom, čo definujeme konštantu app) pridať ešte tento riadok:

app.use(express.json());

Tým voláme takzvané middleware, čo sú procesy, ktoré sa spúšťa medzi prijatím požiadavky a odoslaním odpovede (sú uprostred, preto middleware). Konkrétne express.json() dekóduje telo požiadavke, a pokiaľ v ňom nájde nejaký JSON, tak s ním naplní hodnotu vlastnosti req.body. Bez tohto middleware by sme v req.body nič nenašli.

Teraz už môžeme prejsť do Postman a na novej záložke (1) založiť novú požiadavku. Metóda bude POST (2), vyplníme adresu, nastavíme telo požiadavke (3), vyberieme raw (4) a typ JSON (5).

Do tela požiadavke vyplníme šiesty diel Star Wars, ktorý nám v pôvodnom zozname chýbal. Nezabudnite, že všetko musí byť presne podľa formátu JSON, teda aj mená vlastností musí byť v úvodzovkách. A môžeme požiadavku poslať kliknutím na tlačidlo "Send".

Odoslanie požiadavky pomocou aplikácie Postman na Node.js API server - Node.js

Validácia

Je to trochu odbočka, ale je to tak dôležité, že to nemožno nespomenúť:

Vždy overujte, či dáta, ktorá vám niekto posiela, sú v poriadku a zodpovedajú tomu, čo očakávate.

Zatiaľ si posielate do svojej aplikácie dáta sami, z Postman, takže si nebudete úmyselne posielať zlé dáta. Ale ste si istí, že tam nemáte žiadny preklep? A čo keď bude dáta posielať niekto cudzí?

Rýchlu validáciu si môžete napísať sami - stačilo by overiť, že meno filmu je reťazec a rok premiéry je číslo. Ale opäť - časom budeme potrebovať komplexnejšie validáciu, a prečo písať veľa kódu navyše, keď na ňu už existujú hotové balíky? Jeden z nich, veľmi obľúbený, sa volá Joi.

Nainštalujeme si ho pomocou NPM:

npm install joi

Na začiatok index.js pridajme nasledujúci kód:

const Joi = require('joi');

To, čo sa nám vracia pri použití require(), je trieda, preto veľké J.

Na koniec súboru pridajme funkciu validateMovie():

function validateMovie(movie) {
    const schema = {
        name: Joi.string().min(3).required(),
        year: Joi.number()
    };
    return Joi.validate(movie, schema);
}

Vo funkcii validateMovie() definujeme schému, ktoré hovorí, že meno bude reťazec o minimálnej dĺžke troch znakov a je povinné. Rok musí byť číslo a povinný nie je. Potom pomocou metódy Joi.validate() porovnáme JSON z tela požiadavke (parameter movie) s uvedeným schémou.

Metódu app.post() potom môžeme upraviť napríklad takto:

app.post('/api/movies', (req, res) => {
    const { error } = validateMovie(req.body);
    if (error) {
        res.status(400).send(error.details[0].message);
    } else {
        const movie = {
            id: movies.length + 1,
            name: req.body.name,
            year: req.body.year
        };
        movies.push(movie);
        res.send(movie);
    }
});

Ak požiadavka nezodpovedá schéme, vracia sa nám objekt s vlastnosťou error. V tomto prípade vrátime užívateľovi chybovú hlášku, ktorú nám pripravil Joi, spolu s HTTP kódom 400 Bad Request. Ak je všetko v poriadku, vlastnosť error v objekte neexistuje a zvyšný kód prebehne rovnako ako predtým.

Skúste si teraz poslať z Postman niekoľko POST požiadaviek s validnými alebo so zlými dátami a sledujte správanie aplikácie.

Metóda PUT

Ak ste filmoví znalci, iste vám neuniklo, že máme v kóde zlý rok u štvrtého dielu Star Wars. Poďme ho teda opraviť - naučíme naše API obsluhovať metódu PUT.

Do index.js vložme nasledujúci kód (a súbor nezabudnime uložiť):

app.put('/api/movies/:id', (req, res) => {
    const id = Number(req.params.id);
    const movie = movies.find(movie => movie.id === id);
    if (!movie) {
        res.status(404).send('Film nebyl nalezen.');
        return;
    }
    const { error } = validateMovie(req.body);
    if (error) {
        res.status(400).send(error.details[0].message);
    } else {
        movie.name = req.body.name;
        movie.year = req.body.year;
        res.send(movie);
    }
});

Opakujú sa tu veci, čo sme už použili v iných metódach, takže nie je potrebné kód znova vysvetľovať. Prejdeme opäť do Postman, na novej záložke vyberieme metódu PUT, pošleme ju na koncový bod http://localhost:3000/api/movies/3 a do tela vložíme nasledujúce JSON:

{
    "name": "Star Wars IV",
    "year": 1977
}

Nezabudnite vybrať raw a typ JSON. A potom len overte, pomocou GET požiadavke, že filmy už majú správne nastavený rok premiéry.

Metóda DELETE

A zostáva nám metóda DELETE. To už teraz bude jednoduché:

app.delete('/api/movies/:id', (req, res) => {
    const id = Number(req.params.id);
    const movie = movies.find(movie => movie.id === id);
    if (!movie) {
        res.status(404).send('Film nebyl nalezen.');
    } else {
        const index = movies.indexOf(movie);
        movies.splice(index, 1);
        res.send(movie);
    }
});

Kódu už určite rozumiete. Nezabudnite si pomocou Postman poslať DELETE požiadavku, aby ste otestovali, že to naozaj funguje.

Nabudúce, v lekcii Úvod do MongoDB , si povieme niečo o databázach a hlavne o MongoDB.

Opäť poznámka na záver: ES6 object destructuring

Ak ste si nevedeli rady s premennou error deklarovanou v zložených zátvorkách, jedná sa tzv. Object destructuring. Miesto vysvetľovanie vám radšej ukážem krátky kód:

const obj = {
    a: 1,
    b: 2,
    c: 3
};
const { a, b } = obj;

V konštantách a a b budú uložené údaje, ktoré sa prečítajú zvnútra objektu. Teda v a bude po prebehnutí kódu uložená jednotka a v b dvojka.


 

Mal si s čímkoľvek problém? Stiahni si vzorovú aplikáciu nižšie a porovnaj ju so svojím projektom, chybu tak ľahko nájdeš.

Stiahnuť

Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami

Stiahnuté 379x (3.39 kB)
Aplikácia je vrátane zdrojových kódov v jazyku JavaScript

 

Predchádzajúci článok
Rozbehnutie projektu a prvé riadky v Expressu
Všetky články v sekcii
Node.js
Preskočiť článok
(neodporúčame)
Úvod do MongoDB
Článok pre vás napísal Petr Sedláček
Avatar
Užívateľské hodnotenie:
3 hlasov
Aktivity