Úvod
Když se snažíte dozvědět o webu
vývoji většinou zjistíme, že front-end je výrazně dostupnější než back-end. Existuje pro to mnoho důvodů, zejména pocit okamžité zpětné vazby, který pochází ze změny určitého prvku stránky v kódu a ze zjištění, že se změna aplikuje na web. Tato zpětná vazba je často užitečná pro začátečníky, protože jim umožňuje upravit svůj kód a poučit se ze svých chyb. Bohužel tomu tak není u backendu: často je značné množství práce věnováno nastavení prostředí předem a instalaci závislostí potřebných k tomu, aby se na terminálu objevila jednoduchá zpráva „Hello World“. V komunitě s otevřeným zdrojovým kódem je neustále dosaženo velkého pokroku směrem k usnadnění procesu vývoje rámců a zlepšení zkušeností vývojářů s NodeJs je toho dobrým příkladem kód v Javascriptu pohodlný a nabízí řadu vestavěných nástrojů a funkcí, které jej odlišují od jeho konkurentů. V tomto článku prozkoumáme NodeJs a jeho ekosystém s praktickým přístupem a vytvoříme plně funkční projekt.
Co postavíme?
Aplikace ToDo jsou oblíbeným projektem pro začátečníky, kteří se učí front-end vývoj. To je důvod, proč jsme se rozhodli vytvořit API seznamu úkolů. To nám umožní přidat trvalost dat do našeho rozhraní a dá nám možnost manipulovat s těmito daty (přidáváním, aktualizací, mazáním úkolů atd...).
Finální kód lze nalézt zde.
Naše nástroje
Pro tento projekt použijeme zjednodušený technologický zásobník. Lze to považovat za minimální verzi spousty nástrojů, které najdete v reálných projektech, důvodem je to, že nápady na vyšší úrovni jsou stejné. Podrobnosti implementace a výběr konkrétního nástroje před jiným nejsou pro začátek důležité.
-
NodeJs, jak jsme zmínili, je jedním z nejpopulárnějších frameworků Javascript pro vytváření aplikací na straně serveru.
-
ExpressJs je minimální rámec Javascript používaný nad NodeJS. Urychluje proces vývoje použitím mnoha vestavěných funkcí. Používá se také jako způsob, jak standardizovat vývojové postupy v projektech NodeJS, aby se usnadnilo jeho použití pro inženýry.
-
LowDB je jednoduchá databáze v paměti. Jeho jednoduchost nám umožňuje předvést, jak interagovat s databází v projektu NodeJs, aniž bychom se zabývali pokročilejšími tématy, jako jsou nasazení a konfigurace.
Nyní, když jsme identifikovali všechny nástroje, které budeme používat, pojďme k našim klávesnicím a začněme kódovat!
Instalace
Uzel je dostupný na všech platformách. Všechny instalační příručky lze nalézt na oficiální webové stránce. Uživatelé Windows by se měli ujistit, že přidali uzel cesta k proměnným prostředí, aby jej bylo možné použít na příkazovém řádku.
Budeme také potřebovat nainstalovat npm. Npm je standardní správce balíčků pro NodeJs. Umožní nám to spravovat naše projektové závislosti. Instalační příručku naleznete zde.
Inicializace projektu
Přejděte na odkaz a naklonujte počáteční projekt:
Toto je jednoduchý startovací repozitář pro náš projekt. Obsahuje všechny závislosti, které budeme používat spolu se strukturou souboru projektu. Jakmile dosáhneme, vysvětlíme každý prvek. Otevřete svůj terminál, přejděte na cestu k projektu a spusťte příkaz:
npm install
Tím se nainstalují všechny závislosti projektu uvedené v souboru package.json. package.json je soubor, který se nachází v kořenovém adresáři jakéhokoli projektu Javascript/NodeJs, obsahuje metadata o druhém projektu a používá se ke správě všech závislostí projektu, skriptů a verzí.
Po instalaci všech závislostí můžeme spustit naši aplikaci:
npm run start
„start“ je skript, který jsme specifikovali v balíčku. soubor json. Určuje vstupní soubor do naší aplikace, což je v našem případě app.js.
Ve vašem terminálu by se nyní měla objevit následující zpráva:
To znamená, že se náš server úspěšně spustil a naslouchá všem požadavkům odeslaným na port 3000. Podívejme se na app.js a vysvětlíme, co se děje zde:
App.js je náš vstupní soubor projektu (a jediný v tomto bodě). Vytvoříme instanci expresní aplikace s názvem app, určíme, že všechny požadavky, které mají http metodu „GET“ a podcestu „/“, budou zpracovány touto cestou, předáme funkci zvanou middleware, která převezme objekt požadavku a odpovědi jako parametry. To je zásadní, protože požadavek obsahuje všechny informace potřebné pro jeho zpracování (parametry, tělo požadavku, hlavičky požadavku atd..) a objekt odpovědi je ten, který bude vrácen klientovi. Začneme tím, že pošleme zprávu „Ahoj světe“. Poté zařídíme, aby naše aplikace naslouchala všem příchozím požadavkům na zadaný port (v našem případě 3000) a zaprotokolujeme zprávu „Poslouchám port 3000“, která indikuje, že naše aplikace je spuštěna a připravena přijímat požadavky.
Otevřete terminál a do řádku odkazů zadejte „localhost:3000/“ a stiskněte Enter. Toto je zadaná cesta, kterou můžeme použít k místnímu přístupu k našemu serveru. Obdržíte následující zprávu:
Konfigurace databáze
Lowdb je open-source databáze, která se snadno používá a nevyžaduje žádné specifické nastavení. Obecnou myšlenkou je uložit všechna data do místního souboru json. Po instalaci LowDB (což bylo provedeno, když jsme nainstalovali všechny závislosti), můžeme do db.js přidat následující kód:
Tento kód je velmi podobný kódu, který se nachází v oficiální dokumentaci LowDB. Trochu jsme to upravili pro vlastní případ použití. Pojďme si to vysvětlit řádek po řádku:
Prvních pár řádků je pro import potřebných závislostí. „připojit“ je obslužná funkce dostupná v modulu „cesta“. Je to jeden ze základních modulů NodeJs, který nabízí mnoho metod pro řešení a zpracování cest. „Low“ a „JSONFile“ jsou dvě třídy vystavené LowDB. První vytvoří instanci souboru json, který bude obsahovat naše data. Druhý vytvoří skutečnou instanci databáze, která na něj bude působit. Konečně „lodash“ je jednou z nejpoužívanějších knihoven javascriptu, která nabízí širokou škálu obslužných funkcí pro běžné programovací úlohy. Přidáváme ji do naší databáze, abychom mohli používat její pokročilé metody ke zpracování našich dat.
Nejprve určíme cestu k souboru db.json. Je to soubor, který bude obsahovat naše data a bude předán do LowDB. Pokud soubor není v zadané cestě nalezen, LowDB jej vytvoří.
Poté předáme cestu k souboru adaptéru LowDB a předáme ji naší nové instanci databáze LowDB. Proměnná „db“ pak může být použita pro komunikaci s naší databází. Jakmile je instance databáze vytvořena, čteme ze souboru json pomocí db.read(). Tím se nastaví pole „data“ v naší instanci databáze, abychom měli přístup k obsahu databáze. Všimněte si, že jsme tomuto řádku předcházeli „čekat“. Tím je upřesněno, že vyřešení této instrukce může trvat neznámou dobu a že proces NodeJs musí počkat na své provedení, než bude pokračovat se zbytkem kódu. Děláme to proto, že operace čtení vyžaduje přístup do paměti k určenému souboru a doba provedení tohoto druhu operace závisí na specifikacích vašeho stroje.
Nyní, když máme přístup k datovému poli, nastavíme jej jako objekt obsahující prázdné pole příspěvků, respektive zkontrolujeme, zda soubor obsahuje nějaká předchozí data, a pokud tomu tak není, nastavíme prázdné pole.
Nakonec spustíme db.write(), abychom použili úpravy, které jsme provedli na datech, a exportujeme instanci databáze, aby ji bylo možné použít v jiných souborech v našem projektu.
Pracovní postup obecných požadavků/odpovědí
Zvažte následující diagram:
Ukazuje obecnou architekturu použitou v nepřeberném množství backendových aplikací vytvořených pomocí NodeJs/Express. Pochopení obecného pracovního postupu, který stojí za zpracováním požadavku, vám umožní nejen vytvářet a strukturovat aplikace NodeJs, ale také vám umožní přenést tyto koncepty do prakticky libovolného technického zásobníku podle vašeho výběru. Prozkoumáme různé vrstvy, které do tohoto procesu zasahují, a vysvětlíme jejich role:
## Vrstva požadavku HTTP
Toto je první vrstva v naší aplikaci, představte si ji jako bránu, která přijímá širokou škálu různých požadavků přicházejících od různých klientů, každý požadavek je poté analyzován a předán do vyhrazené části aplikace, kde se s ním zachází.
-
Směrovače: zde máme na mysli směrovače Express, ale tento koncept lze nalézt v mnoha backendových rámcích. Směrovače představují způsob, jak aplikovat logické rozdělení v naší obchodní logice na náš kód, což znamená, že každou sadu prvků, které sdílejí podobné funkce, zpracovává stejný záznam a lze je oddělit od ostatních sad. To má tu výhodu, že každá komponenta kódu je nezávislá na ostatních a snáze se udržuje a rozšiřuje. Konkrétněji a jako příklad, všechny požadavky, které splňují podmínky sdílené cesty URL „/posts“, budou zpracovány stejným routerem. V závislosti na jejich http metodě (GET, POST, atd..) bude použit jiný řadič.
-
Kontroléry: kontrolér přijímá filtrované požadavky od směrovačů, aplikuje další zpracování a volá vhodné servisní metody.
Vrstva obchodní logiky
Tato vrstva je jedinečná v závislosti na konkrétních případech použití aplikace a obchodní logice za ní.
-
Služby: Služby jsou sada metod, které obsahují základní logiku aplikace. Také interagují s databází pomocí ORM/ODM.).
-
Služby třetích stran: mnoho moderních aplikací se rozhodne delegovat část logiky aplikace na vyhrazené služby přístupné prostřednictvím rozhraní API. Služby tohoto druhu mohou být služby zpracování plateb, ukládání statických souborů, upozornění a další.
-
ODM/ORM: ORM a ODM fungují jako prostředníci mezi službami a databází. Jejich úlohou je poskytovat abstrakci na vysoké úrovni na databázi, která umožňuje vývojářům psát kód v programovacím jazyce podle jejich výběru namísto vyhrazených databázových jazyků, jako je SQL.
Vrstva perzistence dat
- Databáze: jak jsme již zmínili dříve, téměř všechny aplikace potřebují určitou formu perzistence dat. Tato část je řešena databázemi a v závislosti na povaze dat, obchodní logice a mnoha dalších aspektech je volba určité databáze před jinou považována za klíčovou pro efektivitu a škálovatelnost aplikace.
Příklad: Přidání příspěvku
Nyní, když rozumíme obecné myšlence architektury, aplikujme ji na náš jednoduchý příklad. Implementujeme funkci přidání příspěvku o úkolu do naší aplikace. Předpokládejme, že každý příspěvek má jedinečné ID, které nám umožní jej později identifikovat v naší databázi, název, který je řetězcem, a objednávku, která je typu integer. Podle našeho schématu začneme implementací routeru. Přidejte následující kód do souboru index.js:
Toto je soubor našeho routeru. Importujeme expresní a metodu „addPost“ z našeho řadiče (tento implementujeme brzy), vytvoříme instanci expresního routeru a navážeme metodu addPost na náš router – což znamená, že pro každý požadavek, který má kořenovou cestu a http metoda „POST“, bude zavolána metoda „addPost“, která ji zpracuje.
Než implementujeme naši metodu do řadiče, odkážeme na nový směrovač v našem hlavním souboru app.js a určíme jeho cestu jako „/posts“: Všechny cesty se zadanými cestami budou předány tomuto směrovači, takže je lze zpracovat různými způsoby ovládání:
Importujeme router a pojmenujeme jej jako „příspěvky“. app.use(“/posts”,..) znamená, že všechny požadavky s podcestou “/posts”, bez ohledu na jejich http metodu, budou směrovány na zadaný router.
Mezi další změny app.js patří import konfiguračního souboru databáze, aby mohl být proveden, a použití express.json() jako middlewaru, který nám umožní přístup k objektu těla požadavku.
Nyní, když jsou naše trasy nastaveny, můžeme přidat metodu „addPost“ do souboru controller.js:
„addPost“ je middlewarová funkce, která jako parametry bere požadavek, objekty odezvy a další funkci. Když je zavolána další funkce, proces se přesune na další middleware v řetězci nebo ukončí požadavek. V kódu metody extrahujeme název a objednávku z těla požadavku a předáme je jako parametry servisní funkci „createPost“. Tato funkce převezme atributy příspěvku, vytvoří nový příspěvek a vrátí jej. Jakmile je nový příspěvek vytvořen, vrátíme jej klientovi spolu se stavovým kódem 200, což znamená, že požadavek byl úspěšný. Můžete si všimnout, že náš kód je vložen do bloku try/catch, aby zachytil jakoukoli neočekávanou chybu a předal ji dalšímu middlewaru. Za nejlepší praxi se považuje připojit ke všem směrovačům middleware pro zpracování chyb, který extrahuje chybu a vrátí klientovi smysluplnou chybovou zprávu.
Nyní zbývá pouze implementovat funkci „createPost“ v service.js:
Jak jsme zmínili dříve, když jsme vysvětlovali různé vrstvy architektury, vrstva služeb interaguje s řešením ukládání dat pomocí ORM/ODM. V našem příkladu však nebudeme muset používat samostatný ORM, protože Lowdb přichází s vestavěnou podporou Javascriptu. Všechny podrobnosti o jeho syntaxi lze nalézt v dokumentaci.
Metoda „createPost“ přijímá název a pořadí jako parametry a používá je k vytvoření objektu příspěvku. Pro jedinečné ID používáme vyhrazenou knihovnu nazvanou „nanoid“, která generuje jedinečnou sekvenci znaků. Přidáme nový příspěvek do pole příspěvků v databázi a zapíšeme tyto změny; nový příspěvek pak funkce vrátí.
Nyní, když je „createPost“ připraven, funkce přidávání příspěvků je nyní dokončena a spuštěna. Testujeme to pomocí Postmana, oblíbeného nástroje pro testování API:
Jako metodu http pro požadavek vybereme „POST“ spolu se zadanou cestou adresy URL „localhost:3000/posts“. Do sekce těla přidáme název a objednávku jako formát json a odešleme požadavek. Jak je uvedeno výše, spolu s nově vytvořeným příspěvkem obdržíme stav 200 OK.
Závěr
V tomto projektu bylo prozkoumáno mnoho konceptů a nápadů: Zabývali jsme se tím, jak nainstalovat a nastavit naše projektové prostředí, naučili jsme se, jak nakonfigurovat LowDB pro lokální perzistenci dat, prozkoumali jsme obecnou architekturu backendových aplikací NodeJS/Express a viděli, jak aplikujte to na jednoduchém příkladu. Nakonec jsme naši aplikaci otestovali pomocí Postmana.
Záměrem zde bylo odhalit zjednodušenou verzi všeho, co jde do budování moderních backendových aplikací. Jak jsme viděli dříve, NodeJs je výkonný nástroj, který nám umožňuje vytvářet jednoduchá a složitá API. V kombinaci se svým bohatým ekosystémem frameworků, jako je express a množstvím nástrojů a knihoven pro téměř jakýkoli případ použití, jde o legitimní řešení pro moderní backendový vývoj – řešení, které doporučujeme naučit se a ovládat.