NOVINKA – Víkendový online kurz Software tester, který tě posune dál. Zjisti, jak na to!
NOVINKA - Online rekvalifikační kurz Java programátor. Oblíbená a studenty ověřená rekvalifikace - nyní i online.

Lekce 4 - Kompletní RESTful API v Node.js

V minulé lekci, Rozběhnutí projektu a první řádky v Expressu, jsme si připravili pracovní prostředí a začali jsme používat knihovnu Express.

V následujícím Node.js tutoriálu implementujeme kompletní RESTful API v Node.js pro databázi filmů. Cestou se naučíme používat několik užitečných nástrojů jako jsou nodemon a Postman.

Pro získání přehledu doporučujeme nyní zhlédnout lekci Dokumentace k Node.js API, kde je kompletně popsané API, které nyní budeme několik lekcí vytvářet. Na konci lekce je pak odkaz, který vede zpět sem.

Teď už se ale pustíme do instalace nástroje Postman.

Postman

Postman je software pro testování a volání různých API, včetně našeho RESTful. Umožňuje posílat, testovat a dokumentovat HTTP požadavky a odpovědi. Ke stažení je volně k dispozici na Download Postman. Po stažení spustíme klasický instalátor a aplikaci nainstalujeme. Za chvíli ji využijeme 🙂

Založení projektu

Založíme si nový adresář movie-api/ a otevřeme v něm nové okno příkazové řádky z průzkumníku Windows pomocí klávesy Shift a pravého tlačítka myši. Dále budeme používat balíčkovací systém npm pro jehož inicializaci potřebujeme soubor package.json. Pro jeho vytvoření zadáme do příkazové řádky:

npm init --yes

Ihned poté provedeme instalaci frameworku Express. Z příkazové řádky spustíme:

npm install express@~4.18.1

Prostředí máme připravené. V projektu poté vytvoříme ještě soubor index.js, do kterého napíšeme následující kód:

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

app.listen(port, () => console.log("Listening on port " + port + "..."));

Nodemon

Dosud jsme při každé úpravě kódu museli naši aplikaci restartovat. Nástroj nodemon nabízí lepší řešení. Nodemon je zkratka za node monitor. Hlídá všechny soubory typu .js (a pár dalších typů) v dané složce a podsložkách. Kdykoli se některý z těchto souborů změní, nodemon aplikaci sám restartuje. Veškeré změny tak můžeme rovnou vyzkoušet.

Instalace nodemon

Nodemon nainstalujeme opět pomocí npm. Nainstalujeme jej globálně, což provedeme s použitím parametru -g:

npm install -g nodemon

Nyní aplikaci spustíme. Pro spuštění aplikace zadáme do příkazové řádky:

nodemon index.js

Metoda GET

Metodu GET jsme používali již minule. Nově bude vracet všechny filmy nebo detail jednoho konkrétního filmu. K tomu budeme samozřejmě nejdříve potřebovat databázi filmů.

Příprava dat

Pro začátek nebudeme ještě používat databázi (tu si přidáme v některé z příštích lekcí), ale budeme filmy držet 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 filmech bychom mohli uchovávat mnohem více dat (a v databázi také budeme), zatím nám však postačí id filmu, jeho jméno a rok premiéry.

Implementace metody GET není náročná. Přehled cest jsme si udělali již dříve a metodu GET už umíme:

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 prvním volání metody app.get() bez parametru se ptáme na všechny filmy, vrátí se tedy celé pole. Při druhém volání požíváme parametr id, pomocí metody find() na vyhledávání v poli najdeme správný film a vrátíme ho. Pokud by film neexistoval, vrátíme chybovou hlášku a HTTP kód 404 s hláškou Film nebyl nalezen..

Nyní již aplikaci nemusíte restartovat, stačí kód uložit. Po zadání http://localhost:3000/api/movies do adresního řádku se zobrazí seznam filmů:

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

Když přidáme ještě jedno lomítko a id filmu, zobrazí se jen data o konkrétním filmu:

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

Pokud zadáme id, pro které film neexistuje, zobrazí se chybová hláška. Ve vývojářských nástrojích pod klávesou F12 se v panelu Network přesvědčíme, že nám server vrátil kód 404:

Node.js - Serverový JavaScript

Metoda POST

Určitě jste si všimli, že se pole s filmy v prohlížeči nezobrazilo moc hezky. Prohlížeč je totiž určený pro vykreslování webových stránek, ne pro zobrazování polí. Požadavek s metodou POST bychom dokonce měli problém i odeslat. Proto přichází na scénu Postman. Program spustíme:

Posílání POST požadavku na Node server v aplikaci Postman - Node.js - Serverový JavaScript

Po spuštění zvolíme metodu GET (1), do adresního řádku napíšeme totéž, co do adresního řádku prohlížeče (2), a klikneme na tlačítko Send (3).

Zobrazí se nám seznam filmů nebo konkrétní film, podle toho, s jakou cestou jsme požadavek poslali. Kromě toho nám Postman ukazuje HTTP kód 200 OK, se kterým přišla odpověď (4) a mnoho dalších informací.

Můžeme si ještě ověřit, že vrátí kód 404 při zadání GET požadavku na neexistující id filmu. Stejně jako v prohlížeči si v něm můžeme vytvářet záložky na různé požadavky pomocí tlačítka + (5).

Od teď už budeme všechny požadavky na naše API posílat pomocí Postmana.

Implementace POST

Když máme Postmana, můžeme si naimplementovat metodu POST. Do index.js vložme následující kód:

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);
});

Po přidání kódu výše stačí soubor index.js pouze uložit. Aplikaci již nemusíme restartovat.

Nyní voláme metodu app.post(). Požadavek posíláme na cestu bez parametru, protože id nový film ještě nemá přiřazené. Nyní ho tvoříme jako délku pole plus jedna. To sice nemusí být vždycky správně, ale vzhledem k tomu, že časem to za nás bude dělat databáze, tak nám to protentokrát bude stačit. Pak už jen přidáme film do databáze a také ho zobrazíme jako odpověď. V odpovědi se film zobrazí včetně nově vytvořeného id.

Aby kód fungoval, musíme na začátek souboru ihned po definici konstanty port přidat následující řádek:

app.use(express.json());

Teď si blíže vysvětlíme jeho funkci. Voláme jím takzvané middleware, což jsou procesy, které se spouští mezi přijetím požadavku a odesláním odpovědi (jsou uprostřed, proto middleware). Konkrétně express.json() parsuje tělo požadavku. Pokud v něm najde nějaký JSON, naplní s ním hodnotu vlastnosti req.body. Bez tohoto middleware bychom v req.body nic nenašli.

Nyní již můžeme přejít do Postmana a na nové záložce (1) založit nový požadavek. Metoda bude POST (2), vyplníme adresu, nastavíme tělo požadavku (3), vybereme raw (4) a typ JSON (5).

Do těla požadavku vyplníme šestý díl Star Wars, který nám v původním seznamu chyběl:

{
    "name": "Star Wars VI",
    "year": 1983
}

Vše musí být přesně podle formátu JSON, tedy i jména vlastností musí být v uvozovkách. Požadavek odešleme kliknutím na tlačítko Send:

Odeslání požadavku pomocí aplikace Postman na Node.js API server - Node.js - Serverový JavaScript

Validace dat

Zatím jsme data do aplikace posílali sami. Je tedy samozřejmé, že si do aplikace nebudeme úmyslně posílat špatná data. Může se nám ale snadno stát, že uděláme omylem nějaký překlep. A co když nebudeme data do aplikace posílat my, ale někdo jiný?

Je zásadně vhodné vždy pečlivě ověřit, jestli data, která nám někdo posílá, jsou v pořádku a odpovídají tomu, co očekáváme.

Rychlou validaci si můžeme napsat sami. U naší filmové databáze by stačilo ověřit, že jméno filmu je řetězec a rok premiéry je číslo. Ale opět - časem budeme potřebovat komplexnější validaci, a proč psát spoustu kódu navíc, když na ni už existují hotové balíčky? Jeden z nich, velmi oblíbený, se jmenuje Joi.

Instalace Joi

Pro instalaci nástroje Joi opět použijeme balíčkovací systém npm. Z příkazové řádky spustíme:

npm install joi@~17.6.0

Pomocí @~17.6.0 za názvem knihovny jsme npm řekli, že chceme verzi, kde je major verze 17 a minor verze 6. Verze tedy odpovídá formátu 17.6.x. Vyhneme se tak nefunkčnosti ukázek v dalších verzích knihovny, kde může autor zvolit jinou syntaxi.

Implementace Joi

Na začátek souboru přidáme následující kód:

const Joi = require('joi');

Při použití require() se nám vrací třída, proto velké J. Na konec souboru poté přidáme funkce validateMovie():

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

Ve funkci validateMovie() definujeme schéma, které říká, že jméno bude řetězec o minimální délce tří znaků a je povinné. Rok musí být číslo a povinný není. Potom pomocí metody schema.validate() porovnáme JSON z těla požadavku (parametr movie) s uvedeným schématem.

Metodu app.post() poté upravíme tímto způsobem:

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);
    }
});

Pokud požadavek neodpovídá schématu, vrací se nám objekt s vlastností error. V tomto případě vrátíme uživateli chybovou hlášku, kterou nám připravil Joi, spolu s HTTP kódem 400 Bad Request. Pokud je vše v pořádku, vlastnost error v objektu neexistuje a zbylý kód proběhne stejně jako předtím.

Nyní je na čase poslat z Postmana několik požadavků, s validními ale i nevalidními daty, a vyzkoušet chování aplikace.

Metoda PUT

Filmovému znalci neunikne, že máme v kódu špatný rok u čtvrtého dílu Star Wars. Pojďme ho tedy opravit - naučíme naše API obsluhovat metodu PUT.

Do index.js vložíme následující kód a soubor uložíme:

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í se tu věci, které jsme již použili v jiných metodách, takže není třeba kód znovu vysvětlovat.

Přejdeme opět do Postmana, na nové záložce vybereme metodu PUT, pošleme ji na koncový bod http://localhost:3000/api/movies/3, vybereme možnost raw, typ JSON a do těla vložíme:

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

A klikneme na tlačítko Send. Poté pomocí GET požadavku ověříme, že film již má správně nastavený rok premiéry.

Metoda DELETE

Zbývá nám už jen metoda DELETE, naštěstí velmi jednoduchá. Na konec souboru přidáme kód:

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);
    }
});

Pomocí Postmana si vyzkoušíme poslat DELETE požadavek, abychom otestovali, že to opravdu funguje :-)

To by bylo pro tuto lekci vše.

V další lekci, Úvod do MongoDB, si nainstalujeme databázi MongoDB a zkusíme se k ní také připojit.


 

Měl jsi s čímkoli problém? Stáhni si vzorovou aplikaci níže a porovnej ji se svým projektem, chybu tak snadno najdeš.

Stáhnout

Stažením následujícího souboru souhlasíš s licenčními podmínkami

Staženo 376x (3.39 kB)
Aplikace je včetně zdrojových kódů v jazyce JavaScript

 

Předchozí článek
Rozběhnutí projektu a první řádky v Expressu
Všechny články v sekci
Node.js - Serverový JavaScript
Přeskočit článek
(nedoporučujeme)
Úvod do MongoDB
Článek pro vás napsal Petr Sedláček
Avatar
Uživatelské hodnocení:
214 hlasů
Aktivity