Hogyan építsünk Rest API-t NodeJS, Express és MySQL segítségével

A JavaScript és a MySQL ismeretében az Express segítségével építhetjük meg NodeJS API-nkat.

Megtettem egy kis kutatást, és megpróbáltam egy API-t fejleszteni a semmiből.
szeretem leegyszerűsíteni a dolgokat, és megpróbálom elkerülni a kódduplikációt.

Ez az útmutató megmutatja, hogyan építhetünk egy API-t a semmiből:
Megtanuljuk, hogyan hozzunk létre útvonalakat,
hogyan használjuk a mysql2-t, hogyan konfiguráljuk és csatlakozunk az adatbázishoz, és hogyan futtatunk lekérdezéseket preparált utasításokkal.
Hogyan hozzon létre egy olyan middleware-t, amely a req, res és a next callback mellett további argumentumot is kaphat.
Megtanulja, hogyan ellenőrizheti a request objektumból származó adatokat az Express Validator modul segítségével.
Megtanulja, hogyan használhatja a JWT modult egy token létrehozására a felhasználó számára, a token ellenőrzésére és a tokenben tárolt objektum kinyerésére.
Megtanulja továbbá, hogyan adhat engedélyt a felhasználóknak egy adott útvonal elérésére a felhasználói szerepkörük alapján.

Technológiák és csomagok:

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

MySQL telepítése:

Én WSL-t használok, és ebben a bemutatóban megnézheted, hogyan kell a MySQL-t WSL-ben telepíteni.
Ezzel a paranccsal kell meggyőződnöd arról, hogy a MySQL fut:

sudo service mysql status
Enter fullscreen mode Exit fullscreen mode

Ha nem fut, csak használd:

sudo service mysql start
Belépés a teljes képernyős módba Kilépés a teljes képernyős módból

Alkalmazás áttekintése:

Elkészítünk egy rest API-t a CRUD műveletekhez: felhasználók létrehozása, olvasása, frissítése és törlése.

Létrehozzuk a projekt mappát és telepítjük az összes függőséget:

mkdir mysql-node-express && cd mysql-node-expressnpm init -ynpm i express express-validator mysql2 cors dotenv jsonwebtoken -Snpm i nodemon -D
Belépés a teljes képernyős módba Kilépés a teljes képernyős módból

Menjünk a package.json fájlba és változtassuk meg a “main” értéket “src/server.js”-re, és adja hozzá ezeket a szkripteket a scripts objektumhoz:

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

a package.json fájlnak így kell kinéznie:

Hozzon létre .env fájlt:

A .env fájlt fogjuk használni az összes környezeti változók kezelésére.
A .env fájl egy rejtett fájl, amely lehetővé teszi számunkra a környezeti változóink testreszabását az ENV VARIABLE = VALUE szintaxis segítségével.
Ezeket a változókat a már telepített dotenv modul segítségével töltjük be.
A .env fájlt a környezet különböző fázisaiban (develop / stage / production környezetek) definiálhatjuk.

Hozza létre a .env fájlt, másolja be a következő sorokat, és frissítse a fájlt a MySQL db_name, db_username és jelszóval:

# DB ConfigurationsHOST=localhostDB_USER=db_usernameDB_PASS=db_passwordDB_DATABASE=db_name# local runtime configsPORT=3000SECRET_JWT=supersecret
Enter fullscreen mode Exit fullscreen mode

Create nodemon.json file:

A nodemon egy olyan eszköz, amely a node.js alapú alkalmazások fejlesztését segíti azáltal, hogy automatikusan újraindítja a node alkalmazást, amikor a célkönyvtárban fájlváltozásokat észlel.
A nodemon egy helyettesítő wrapper a node számára. A node parancs helyett a nodemon parancsot kell használnunk a parancssoron a szkriptünk futtatásához.
A nodemon parancssoron történő futtatása közben könnyen hozzáadhatunk konfigurációs kapcsolókat, például:

nodemon --watch src
Enter fullscreen mode Exit fullscreen mode

Egy fájlt is használhatunk (nodemon.json) segítségével adhatjuk meg az összes kapcsolót.
Ha egy könyvtárban több fájlt szeretnénk figyelni, akkor a “watch” tömbben hozzáadhatjuk a könyvtárat.
Ha egy adott kiterjesztést akarunk keresni (például egy ts fájlt), akkor használhatjuk az “ext” tulajdonságot.
Ha figyelmen kívül akarunk hagyni néhány fájlt, akkor meghatározhatjuk őket az “ignore”‘ tömbben, és így tovább…
Ezt a fájlt leginkább akkor használom, amikor NodeJS alapú szervert készítek typescript alapján, de szerintem egyszerűbb, ha több helyen tudjuk felvenni az alkalmazásunk konfigurációit.
Ez a fájl opcionális.

Készítsük el a nodemon.json fájlt, és ezt adjuk hozzá a fájlhoz:

{ "watch": , "ext": ".js", "ignore": }
Enter fullscreen mode Exit fullscreen mode

Hozzuk létre az src mappát:

mkdir src && cd src
Enter fullscreen mode Exit fullscreen mode

A src mappában hozzon létre almappákat: controllers, models, routes, middleware, db és utils:

mkdir controllers models routes middleware db utils
Belépés a teljes képernyős módba Kilépés a teljes képernyős módból

Express szerver beállítása:

A src könyvtárban hozzuk létre a server.js fájlt, és másoljuk be ezeket a sorokat:

Ebben a fájlban importáljuk az express-t a többi API létrehozásához, és használjuk az express.json() funkciót a JSON payloadot tartalmazó bejövő kérések elemzésére.

A dotenv modult is importáljuk a .env config fájlt, hogy megkapjuk a port számát a szerver futtatásához.

A userRouter-t is importáljuk.

Ezután van egy middleware-ünk, amely a 404 hibákat kezeli → ha valaki egy nem létező végpontot keres, akkor ezt a hibát kapja: “Endpoint Not Found” 404 státuszkóddal. Ezután hiba middleware-t használunk, amely az előző útvonalakról kapja meg a hibaadatokat. ha next(err) meghívásra kerül, akkor a 404-es middleware-t láthatjuk példaként.
A portot hallgatjuk a.env fájlból és kiírjuk a konzolra, hogy a szerver fut.

MySQL adatbázist és felhasználói táblát hozunk létre:

A db könyvtárban létrehozzuk a create-user-db.sql fájlt és copy-paste ezeket a sorokat:

Ezzel a szkripttel először eldobjuk az adatbázist, ha létezik, hogy hiba esetén gyorsan visszaállítható legyen (ezt a sort ki lehet kommentelni, ha akarjuk), majd, ha nem létezik, létrehozzuk az adatbázist. Ezt állítjuk be aktív adatbázisnak, és létrehozunk egy “user” táblát az összes oszloppal (id, felhasználónév, stb.), ami ismét lehetővé teszi a kényelmes visszaállítást, ha szükséges. Ezt a lekérdezést futtathatjuk az adatbázis-kliensben, ha használunk ilyet.

Ha wsl-t használunk, akkor a db könyvtárban futtathatjuk:

mysql -u -p < create-user-db.sql
Enter fullscreen mode Exit fullscreen mode

Configure and Connect to MySQL database:

Készítsünk egy további fájlt a db könyvtárban, a neve db-connection.js, és copy-paste ezt:

Ebben a fájlban először importáljuk a dotenv modult, és az.env fájlból olvassuk be az adatbázis konfigurációs adatait, mint a db host, db user.

Ellenőrizzük a kapcsolatot, ha valami gond van az adatbázissal, majd feloldjuk a kapcsolatot.

Egy query metódusunk van, amely visszaad egy ígéretet a lekérdezés eredményéről.

Egy try-catch blokkot használunk a gyakori MySQL hibák rögzítésére és a megfelelő HTTP státuszkódok és üzenetek visszaadására.

A fájl végén létrehozzuk a DBConnection osztály egy példányát és használjuk a query metódust, a model.js-ben (amit a következő lépésben fogunk látni) pedig ismét a query metódust fogjuk használni.

Hibakezelő létrehozása:

A következőkben létrehozzuk a hibakezelőnket.

Ezért először létrehozzuk a HttpException.utils.js fájlt az utils könyvtárban, és copy-paste a következőket:

A HttpException osztály örökli az Error osztályt.
A konstruktor megkapja a státuszt, az üzenetet és az adatokat. Az üzenet változót a super(message) segítségével átadjuk a szülő konstruktornak, majd inicializáljuk a status, message és data példányváltozókat.

Ezután létrehozunk egy middleware hibakezelőt a middleware könyvtárban.
Elkészítünk egy hibát. middleware.js fájlt és copy-paste a következőket:

A fájl alján láthatjuk, hogy milyen lesz az objektum.

A middleware megkapja a req, res, és next callback-et, de kap egy további argumentumot is, az error-t (a next(error) használatával, mielőtt eljutnánk ehhez a middleware-hez).

A destructuring segítségével megkapjuk a változókat a hiba objektumból, és a státuszt 500-ra állítjuk, ha korábban nem volt beállítva.

Azt követően, hogy a státusz 500-e, gondoskodunk arról, hogy az üzenet megváltozzon, így a felhasználó egy általános belső szerver hibaüzenetet fog kapni anélkül, hogy felfedné a hiba pontos természetét.

Ezután létrehozunk egy hibaobjektumot a típus, a státusz és az üzenet tulajdonságokkal (az adatok opcionálisak).

Létrehozzuk az utils (segédprogramok) fájlokat:

Az utils könyvtárban létrehozunk még két fájlt, a common.utils.js-t és a userRoles.utils.js-t.

common.utils.js:

Ez a funkció segít az előkészített lekérdezések több mezőjének beállításában kulcs-érték párokkal.
ColumnSet a kulcs =? párok tömbje,
Az értékeknek ezért ugyanabban a sorrendben kell lenniük, mint a columnSet tömbnek.

userRoles.utils.js:

module.exports = { Admin: 'Admin', SuperUser: 'SuperUser'}
Belépés a teljes képernyős módba Kilépés a teljes képernyős módból

Async funkció létrehozása:

Készítsünk egy másik fájlt awaitHandlerFactory.middleware.js néven a middleware könyvtárban és copy-paste ezt:

Általában tudjuk, hogy a middleware csak egy aszinkron metódus, amely megkapja a req, a res és a next argumentumokat, tehát ha azt akarjuk, hogy ez a middleware kapjon egy további argumentumot, akkor ezt így fogjuk csinálni (a következő lépésben ezt fogjuk használni az auth middleware-ben is).

Ez a függvény kap egy visszahívást, lefuttatja a middleware szkriptet, és megpróbálja kiváltani ezt a visszahívást a try blokkban.
Ha itt valami rosszul megy, akkor elkapja a hibát, és használjuk a next(err) (ami átadja a következő middleware-nek => error.middleware.js).

Authentication Middleware létrehozása:

Egy másik middleware, amelyre szükségünk van, az auth middleware, amelyet a felhasználói jogosultságok ellenőrzésére fogunk használni a JWT modulon keresztül.

A awaitHandlerFactory.middleware.js middleware-hez hasonlóan itt is van egy middleware, amely további argumentumot igényel (ami opcionális) => roles.

A try-catch segítségével a hiba állapotát a catch területen 401-re állítottam be (ha például a token lejárt).

Először a req.headers.authorization-t keressük – ha nincs definiálva a fejlécben, vagy ha a fejléc nem “Bearer ” kezdetű, a felhasználó 401-es választ kap. Ha “Bearer ” kezdetű, akkor megkapjuk a tokent, és a.env fájlból származó titkos kulcsot használjuk annak megfejtéséhez.

A tokent a jwt.verify szinkronfüggvény segítségével ellenőrizzük, amely megkapja a tokent és a secretKey-t, mint argumentumokat, és visszaadja a dekódolt hasznos terhelést, hogy érvényes-e az aláírás és érvényesek-e az opcionális lejárati, közönség vagy kibocsátó mezők. Ellenkező esetben hibát dob.

Most, a felhasználói azonosító keresésével megtalálhatjuk az ezzel a tokennel rendelkező felhasználót.
Ha a felhasználó már nem létezik, akkor minden információ nélkül 401-es kivételt kap.
Ha a felhasználó létezik, akkor ellenőrizzük, hogy az aktuális felhasználó a tulajdonos, aki keresi az útvonalait, vagy hogy a felhasználónak van-e szerepe az adott útvonal eléréséhez.
Mentjük az aktuális felhasználót arra az esetre, ha a következő middleware-en (például a “whoami” útvonalon) szeretné megkapni az adatait.

Adatérvényesítés az Express Validator modul segítségével:

A middleware könyvtárban létrehozunk egy további fájlt, amelyet a req.body tulajdonságainak ellenőrzésére fogunk használni.

Létrehozunk egy almappát a middleware könyvtárban validators néven, és létrehozunk egy fájlt ebben a könyvtárban, userValidator.middleware.js néven. Másoljuk be ezt:

Ebben a fájlban az express-validator modult használtam, amelyet nagyon könnyen használhatunk, amikor néhány tulajdonságot kell ellenőriznünk, ellenőrizni, hogy a tulajdonság létezik-e, vagy egyéni ellenőrzéseket létrehozni egy egyéni üzenettel a felhasználónak, ha valamelyik tulajdonság értéke nem érvényes.

Most elkezdhetjük létrehozni a route, controller és model fájljainkat.

Define Routes:

Készítsük el a user.route.js fájlt a routes könyvtárban, és másoljuk be ezt:

A fenti példa mutatja az útvonalak definiálását. Próbáljuk meg darabokra bontani:

  • Elkészíthetünk egy útvonalat az express.Router() segítségével.Minden útvonal betölthet egy middleware függvényt, amely az üzleti logikát kezeli.A UserController például az összes fő middlewaret hordozza.A router használatához a routert modulként kell exportálni, és a fő alkalmazásban az app.use(router_module) segítségével kell használni.
  • A felhasználói hitelesítéshez és engedélyezéshez auth middleware-t használtunk, a felhasználói token vagy a felhasználói szerepkör ellenőrzéséhez az útvonalhoz.A példánkban néhány útvonal az auth middleware-t használja a felhasználói hitelesítés és engedélyezés ellenőrzésére.Ez a middleware a fő middleware (az üzleti logikát tartalmazó) előtt fog elindulni.A következő callback-et meg kell hívni, hogy átadja a vezérlést a következő middleware metódusnak.Ellenkező esetben a kérés lógva marad.
  • awaitHandlerFactory (try-catch middleware) az összes aszinkron middleware csomagolására szolgál. Így, ha valamelyik middleware hibát dob, az awaitHandlerFactory elkapja a hibát. láthatjuk, hogy az összes middleware függvényünket awaitHandlerFactory middleware-rel csomagoljuk, ami segít nekünk abban, hogy a try-catch használatával egy helyen kezeljük a hibákat.
  • Ezeken kívül van a createUserSchema, updateUserSchema és validateLogin sémánk a test érvényesítésére, mielőtt a következő middleware-t elindítanánk.

A HTTP módszer szintaxisa a következő:

Hozzuk létre a Controller-t:

Készítsük el a user.controller.js fájlt a controllers könyvtárban, és másoljuk be ezt:

Mint már említettük, a controller fájl tartalmazza az üzleti logikánkat az útvonalaink kezeléséhez.
Példánkban néhány metódus a UserModel osztályt használja az adatbázis lekérdezésére az adatok megszerzéséhez.
Az adatok visszaküldéséhez az egyes köztes eszközökben az res.send(result) segítségével választ küldünk az ügyfélnek.

Hozzuk létre a Modellt:

És hozzuk létre a user.model.js fájlt a models könyvtárban, és copy-paste ezt:

Ez az osztály kapcsolatot teremt a vezérlő és az adatbázis között.
Itt van az összes metódus, amely megkapja az argumentumokat a vezérlőtől, lekérdezést készít, előkészíti az utasításokat, csatlakozik az adatbázishoz a db-connection osztály lekérdezési metódusával, elküldi a kérést az előkészített utasítások tömbjével és visszakapja az eredményt.
Minden függvény visszaadja az eredményt a vezérlőnek.

.gitIgnore:

Ha úgy döntesz, hogy felveszed ezt a projektet a GitHubodra, ne felejts el létrehozni egy .gitignore fájlt, és copy-paste ezt:

node_modules.env
Enter fullscreen mode Exit fullscreen mode

Ez a fájl csak megmondja a gitnek, hogy mely fájlokat hagyja figyelmen kívül.
A node_modules könyvtárat érdemes elkerülni, mert nehézkes és nem szükséges az adattárhoz.
Amikor valaki klónozza ezt a tárolót, az “npm I” parancsot fogja használni az összes függőség telepítéséhez.
A .env fájl figyelmen kívül hagyásával elrejtheted a privát konfigurációidat a kódodat használó más fejlesztők elől.

Vélemény, hozzászólás?

Az e-mail-címet nem tesszük közzé.