Jak vytvořit Rest API pomocí NodeJS, Express a MySQL

Se znalostí JavaScriptu a MySQL můžeme vytvořit naše NodeJS API pomocí Express.

Provedl jsem nějaký výzkum a pokoušel jsem se vytvořit API od nuly.
Rád si věci zjednodušuji a snažím se vyhnout duplicitě kódu.

Tento průvodce vám ukáže, jak vytvořit API od nuly:
Zjistíte, jak vytvořit trasy,
jak používat mysql2, jak konfigurovat a připojit se k databázi a jak spouštět dotazy pomocí připravených příkazů.
Jak vytvořit middleware, který umí kromě req, res a next callback získat další argument.
Zjistíte, jak kontrolovat data z objektu požadavku pomocí modulu Express Validator.
Zjistíte, jak pomocí modulu JWT vytvořit token pro uživatele, ověřit token a získat objekt uložený v tokenu.
Dále se naučíte, jak poskytnout uživatelům oprávnění k přístupu k určité trase na základě jejich uživatelských rolí.

Technologie a balíčky:

  • NodeJS
  • Express
  • mysql2
  • bcryptjs
  • jsonwebtoken
  • express-validator
  • dotenv
  • cors

Instalace MySQL:

Používám WSL a pomocí tohoto návodu se můžete podívat, jak nainstalovat MySQL ve WSL.
Tímto příkazem se musíte ujistit, že MySQL běží:

sudo service mysql status
Vstup do celoobrazovkového režimu Ukončení celoobrazovkového režimu

Pokud neběží, stačí použít:

sudo service mysql start
Vstup do celoobrazovkového režimu Ukončit celoobrazovkový režim

Přehled aplikací:

Vytvoříme rest API pro operace CRUD: vytváření, čtení, aktualizace a mazání uživatelů.

Vytvořte složku projektu a nainstalujte všechny závislosti:

mkdir mysql-node-express && cd mysql-node-expressnpm init -ynpm i express express-validator mysql2 cors dotenv jsonwebtoken -Snpm i nodemon -D
Vstupte do celoobrazovkového režimu Ukončete celoobrazovkový režim

Přejděte do souboru package.json a změňte hodnotu “main” na “src/server.js” a přidejte tyto skripty do objektu scripts:

"start": "node src/server.js","dev": "nodemon"
Enter fullscreen mode Exit fullscreen mode

package.json by měl vypadat takto:

Create .env file:

Soubor .env budeme používat pro správu všech našich proměnných prostředí.
Soubor .env je skrytý soubor, který nám umožňuje přizpůsobit naše proměnné prostředí pomocí syntaxe ENV VARIABLE = VALUE.
Tyto proměnné se načítají pomocí modulu dotenv, který jsme již nainstalovali.
Soubor .env lze definovat v různých fázích prostředí (vývojové / fázové / produkční prostředí).

Vytvořte soubor .env, zkopírujte následující řádky a aktualizujte soubor pomocí svého db_name, db_username a hesla MySQL:

# DB ConfigurationsHOST=localhostDB_USER=db_usernameDB_PASS=db_passwordDB_DATABASE=db_name# local runtime configsPORT=3000SECRET_JWT=supersecret
Vstup do celoobrazovkového režimu Ukončení celoobrazovkového režimu

Vytvořte soubor nodemon.json:

Nodemon je nástroj, který pomáhá vyvíjet aplikace založené na node.js tím, že automaticky restartuje aplikaci node při zjištění změn souborů v cílovém adresáři.
Nodemon je náhradní obal pro node. Místo příkazu node bychom měli pro spuštění našeho skriptu použít příkaz nodemon na příkazovém řádku.
Při spuštění nodemonu na příkazovém řádku můžeme snadno přidat konfigurační přepínače, například:

nodemon --watch src
Vstup do celoobrazovkového režimu Ukončení celoobrazovkového režimu

Můžeme také použít soubor (nodemon.json) pro zadání všech přepínačů.
Pokud chceme sledovat několik souborů v adresáři, můžeme adresář přidat do pole “watch”.
Pokud chceme hledat určitou příponu (například soubor ts), můžeme použít vlastnost “ext”.
Pokud chceme některé soubory ignorovat, můžeme je definovat v poli “ignore”‘ a tak dále…
Tento soubor používám většinou, když vytvářím server s NodeJS založený na typescriptu, ale myslím, že je jednodušší mít více míst pro zahrnutí konfigurace naší aplikace.
Tento soubor je nepovinný.

Vytvořte soubor nodemon.json a přidejte do něj toto:

{ "watch": , "ext": ".js", "ignore": }
Vstup do celoobrazovkového režimu Ukončení celoobrazovkového režimu

Vytvořte složku src:

mkdir src && cd src
Vstupte do celoobrazovkového režimu Ukončete celoobrazovkový režim

Ve složce src vytvořte podsložky: controllers, models, routes, middleware, db a utils:

mkdir controllers models routes middleware db utils
Vstupte do celoobrazovkového režimu Ukončete celoobrazovkový režim

Nastavte server Express:

V adresáři src vytvořte soubor server.js a zkopírujte tyto řádky:

V tomto souboru importujeme express pro sestavení rest API a použijeme express.json() pro parsování příchozích požadavků s JSON payloadem.

Také importujeme modul dotenv pro čtení .env konfigurační soubor, abychom získali číslo portu pro spuštění serveru.

Amportujeme také userRouter.

Poté máme middleware, který zpracovává chyby 404 → pokud někdo hledá koncový bod, který neexistuje, zobrazí se mu tato chyba: “Endpoint Not Found” se stavovým kódem 404. Poté použijeme chybový middleware, který bude získávat chybová data z předchozích tras. pokud se zavolá next(err), můžete jako příklad vidět middleware 404.
Posloucháme na portu ze souboru.env a vypíšeme na konzoli, že server běží.

Vytvoříme databázi MySQL a tabulku uživatelů:

V adresáři db vytvoříme soubor create-user-db.sql a zkopírujeme a vložíme tyto řádky:

V tomto skriptu nejprve zrušíme databázi, pokud existuje, abychom ji mohli v případě omylu rychle obnovit (pokud chcete, můžete tento řádek zakomentovat), poté vytvoříme databázi, pokud neexistuje. Nastavíme ji jako naši aktivní databázi a vytvoříme tabulku “user” se všemi sloupci (id, uživatelské jméno atd.), což opět umožní pohodlný reset v případě potřeby. Tento dotaz můžete spustit v databázovém klientu, pokud jej používáte.

Pokud používáte wsl, v adresáři db můžete spustit:

mysql -u -p < create-user-db.sql
Vstup do celoobrazovkového režimu Ukončení celoobrazovkového režimu

Konfigurace a připojení k databázi MySQL:

Vytvoříme další soubor v adresáři db s názvem db-connection.js a zkopírujeme a vložíme tento:

V tomto souboru nejprve importujeme modul dotenv a pomocí něj načteme ze souboru.env konfigurační informace o databázi jako db host, db user.

Zkontrolujeme připojení v případě, že je s databází nějaký problém, a poté připojení uvolníme.

Máme metodu query, která vrací slib výsledku dotazu.

Použijeme blok try-catch pro zachycení běžných chyb MySQL a vrácení příslušných stavových kódů HTTP a zpráv.

Na konci souboru vytvoříme instanci třídy DBConnection a použijeme metodu query a v modelu.js (který uvidíme v dalším kroku) použijeme opět metodu query.

Vytvoříme obsluhu chyb:

Dále vytvoříme naši obsluhu chyby.

Pro to nejprve vytvoříme soubor HttpException.utils.js v adresáři utils a zkopírujeme a vložíme následující:

Třída HttpException dědí třídu Error.
Konstruktor získá stav, zprávu a data. Proměnnou message předáme nadřazenému konstruktoru pomocí super(message) a poté inicializujeme instanční proměnné status, message a data.

Poté vytvoříme v adresáři middleware obsluhu chyby.
Vytvoříme error. middleware.js a zkopírujeme a vložíme následující:

Na konci souboru vidíme, jak bude vypadat objekt.

Mediální software dostane req, res a zpětné volání next, ale dostane také další argument, chybu (pomocí next(error), než se dostaneme k tomuto middlewaru).

Pomocí destrukce získáme proměnné z objektu error a nastavíme stav na 500, pokud nebyl nastaven dříve.

Poté, ať už je stav 500, zajistíme změnu zprávy, takže uživatel obdrží obecnou interní chybovou zprávu serveru, aniž bychom odhalili přesnou povahu selhání.

Poté vytvoříme objekt chyby s vlastnostmi typ, stav a zpráva (údaje jsou nepovinné).

Vytvoříme soubory utils (pomocníků):

V adresáři utils vytvoříme další dva soubory, common.utils.js a userRoles.utils.js.

common.utils.js:

Tato funkce pomáhá nastavit více polí pro připravené dotazy pomocí dvojic klíč-hodnota.
ColumnSet pole dvojic klíč =?,
hodnoty by tedy měly být ve stejném pořadí jako pole columnSet.

userRoles.utils.js:

module.exports = { Admin: 'Admin', SuperUser: 'SuperUser'}
Vstup do celoobrazovkového režimu Ukončení celoobrazovkového režimu

Vytvoření funkce Async:

Vytvořte v adresáři middleware další soubor s názvem awaitHandlerFactory.middleware.js a zkopírujte a vložte tento:

Obecně víme, že middleware je pouze asynchronní metoda, která dostane argumenty req, res a next, takže, pokud chceme, aby tento middleware dostal další argument, uděláme to takto (v dalším kroku to použijeme i v middleware auth).

Tato funkce získá zpětné volání, spustí skript middlewaru a pokusí se toto zpětné volání spustit v bloku try.
Pokud se zde něco pokazí, zachytí chybu a my použijeme next(err) (který ji přenese do dalšího middlewaru => error.middleware.js).

Vytvoříme autentizační middleware:

Dalším middlewarem, který potřebujeme, je middleware auth, který budeme používat ke kontrole oprávnění uživatelů prostřednictvím modulu JWT.

Podobně jako u middlewaru awaitHandlerFactory.middleware.js zde máme middleware, který vyžaduje další argument (který je nepovinný) => role.

Pomocí try-catch jsem v oblasti catch upravil chybový stav na 401 (pokud například vypršela platnost tokenu).

Nejprve hledáme req.headers.authorization – ať už není v hlavičce definována, nebo pokud hlavička nezačíná slovem “Bearer “, uživatel dostane odpověď 401.

Podle toho, zda je v hlavičce definována autorizace, uživatel obdrží odpověď 401. Pokud začíná “Bearer “, získáme token a k jeho dešifrování použijeme tajný klíč ze souboru.env.

Token ověříme pomocí synchronní funkce jwt.verify, která dostane jako argumenty token a tajný klíč a vrátí dekódovaný payload, zda je platný podpis a zda jsou platná nepovinná pole expirace, audience nebo issuer. V opačném případě vyhodí chybu.

Nyní můžeme uživatele s tímto tokenem najít vyhledáním id uživatele.
Pokud uživatel již neexistuje, dostane výjimku 401 bez jakýchkoli informací.
Pokud uživatel existuje, zkontrolujeme, zda je aktuální uživatel vlastníkem, který vyhledává své trasy, nebo zda má uživatel roli pro přístup k této trase.
Uložíme aktuálního uživatele pro případ, že by chtěl získat svá data na dalším middlewaru (jako je trasa “whoami”).

Validace dat pomocí modulu Express Validator:

V adresáři middleware vytvoříme další soubor, který budeme používat k ověřování vlastností req.body.

V adresáři middleware vytvoříme podsložku s názvem validators a v ní soubor userValidator.middleware.js. Zkopírujte a vložte tento:

V tomto souboru jsem použil modul express-validator, který lze velmi snadno použít, kdykoli potřebujeme ověřit některé vlastnosti, zkontrolovat, zda vlastnost existuje, nebo vytvořit vlastní kontroly s vlastní zprávou pro uživatele, pokud některá hodnota vlastnosti není platná.

Nyní můžeme začít vytvářet naše soubory route, controller a model.

Definujte Routes:

Vytvořte soubor user.route.js v adresáři routes a zkopírujte a vložte tento:

Výše uvedený příklad ukazuje, jak definovat trasy. Zkusme to rozdělit na části:

  • Můžete vytvořit směrovač pomocí express.Router(). každá trasa může načíst funkci middlewaru, která zpracovává obchodní logiku. například UserController nese všechny hlavní middlewary.Pro použití směrovače by měl být směrovač exportován jako modul a použit v hlavní aplikaci pomocí app.use(router_module).
  • Pro autentizaci a autorizaci uživatele jsme použili middleware auth, pro kontrolu tokenu uživatele nebo role uživatele pro trasu.V našem příkladu některé z tras používají middleware auth pro kontrolu autentizace a autorizace uživatele. tento middleware bude spuštěn před hlavním middlewarem (tím, který obsahuje obchodní logiku). další zpětné volání musí být zavoláno pro předání řízení další metodě middlewaru. jinak požadavek zůstane viset.
  • awaitHandlerFactory (try-catch middleware) se používá pro obalení všech asynchronních middlewarů. Tímto způsobem, pokud některý z middlewarů vyhodí chybu, awaitHandlerFactory tuto chybu zachytí. vidíte, že všechny naše middlewarové funkce jsou obaleny middlewarem awaitHandlerFactory, což nám pomáhá ošetřit naše chyby pomocí try-catch na jednom místě.
  • Dále máme k dispozici schémata createUserSchema, updateUserSchema a validateLogin pro ověření těla před spuštěním dalšího middlewaru.

Syntaxe metody HTTP je:

Vytvořte Controller:

Vytvořte soubor user.controller.js v adresáři controllers a zkopírujte a vložte tento:

Jak bylo uvedeno výše, soubor controller obsahuje naši obchodní logiku pro obsluhu našich tras.
V našem příkladu některé metody používají třídu UserModel k dotazování databáze pro získání dat.
Pro vrácení dat v každém middlewaru použijeme res.send(result) pro odeslání odpovědi klientovi.

Vytvořte model:

V adresáři models vytvořte soubor user.model.js a zkopírujte a vložte tento:

Tato třída vytváří spojení mezi kontrolérem a databází.
Máme zde všechny metody, které získají argumenty z kontroléru, vytvoří dotaz, připraví příkazy, připojí se k databázi pomocí dotazovací metody ze třídy db-connection, odešlou požadavek s připraveným polem příkazů a získají zpět výsledek.
Každá funkce vrátí výsledek do kontroléru.

.gitIgnore:

V případě, že se rozhodnete přidat tento projekt do svého GitHubu, nezapomeňte vytvořit soubor .gitignore a zkopírovat a vložit tento:

node_modules.env
Vstup do celoobrazovkového režimu Ukončení celoobrazovkového režimu

Tento soubor pouze říká systému git, které soubory má ignorovat.
Adresáři node_modules byste se měli vyhnout, protože je těžký a pro repozitář není nezbytný.
Když někdo naklonuje tento repozitář, použije příkaz “npm I” k instalaci všech závislostí.
Ignorace souboru .env slouží ke skrytí vašich soukromých konfigurací před ostatními vývojáři používajícími váš kód.

.

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna.