Web s Express.js - struktura projektu

Express.js je nejpopulárnější Node.js modul, na kterém postavíte web za pár minut, přesto je vhodný i na složité aplikace. Je jednoduchý a rychlý, zároveň velmi flexibilní a robustní.

Startujeme projekt

Mohli bychom si celý proces zkrátit použitím Express generátoru aplikací, ale pro lepší pochopení Node.js se bez něj prozatím obejdeme. Na začátku je nelepší připravit si dobrou strukturu projektu. V Node.js neexistuje strikní adresářová struktura. Svou aplikaci si tak můžete nastavit přesně na míru vašim potřebám. Základem bývají zpravidla následující adresáře:

  • /bin - zahrnuje všechny spustitelné soubory. Dokonce i javascript může být spustitelný díky direktivě #!/usr/bin/env node
  • /config - pokud se vaší aplikaci chystáte nasadit a spouštět na více prostředích, bez konfigurace se neobejdete
  • /controllers nebo /routes - jsou místem kde definujete HTTP rozhraní vaší aplikace, respektive na různá URL navážete konkrétní akce
  • /models nebo /libs - složky pro veškerou serverovou aplikační logiku
  • /public - adresář obsahující veřejně dostupné soubory - zdrojové i produkční css/less/sass/js/ts, obrázky, písma a tak dále.
  • /tests - testovat se rozhodně vyplatí
  • /views - složka s vašimi šablonami

Aby po vás kód přečetl kdokoliv, je dobré se držet výše zmíněných názvů adresářů. Nevyplácí se mít adresářovou strukturu moc hlubokou (vzpomenete si na mě, až budete psát require('../../../../app/models/mysubmodule/someFile.js')). A pro dobrou kulturu je vhodné si hned na začátku stanovit a dodržovat styl, jakým budete psát, například Airbnb JavaScript Style.

Ale těď už k samotné aplikaci. V mém předchozím článku si můžete přečíst jak založit Node.js projekt, ale ve zkratce stačí jen v novém adresáři spustit následující přikazy:

# inicializujeme projekt
npm init

# nainstalujeme a uložíme balíček express
npm install --save express

# nainstalujeme a uložíme šablonovací systém, třeba Handlebars
npm install --save express-handlebars  

Nyní již k samotným souborům

/routes/index.js

Přestože v Expressu neexistuje nic jako controller, díky Routeru můžeme velmi elegantně jemu podobnou strukturu vytvořit. Pro každou stránku či API rozhraní lze definovat specifický callback (funkci), který požadavek vyřídí. Metoda, kterou callback registrujeme, definuje HTTP metodu, pro kterou callback platí. V příkladě níže zpracováváme pouze GET requesty. Prvním parametrem je pak definice URL, kterou pak callback, vložený jako druhý parametr, zpracovává.

const express = require('express');

// create a router instance
const router = express.Router();

// homepage
router.get('/', (req, res) => {

    // render index.hbs template
    res.render('index');
});

module.exports = router;  

Callback má pak dva parametry. Prvním je req - request, objekt obsahující informace přicházející z prohlížeče, zejména hlavičky, tělo dotazu a kompletní URL včetně všech parametrů. Druhým je res - response, objekt umožňující odeslat klientovi odpověď. Buď přímo metodou send(), která dokáže odeslat text, stejně jako JSON objekt, či metodou render() přímo jako odpověď vykresit šablonu s daty, které lze předat druhým parametrem metody.

/app.js - váš aplikační bootstrap

Aby nám aplikace fungovala, je třeba vytvořit instanci samotné Express aplikace a zapojit do ní šablonovací systém a všechny routery. Šablonovacímu systému prozradíme jakou mají příponu (v našem případě .hbs), kde se nachází layout - společná základní šablona, a nakonec ho zapojíme do Expressu.

const express = require('express');  
const path = require('path');  
const expressHandlebars = require('express-handlebars');

const routes = require('./routes');

var app = express();

// set up view engine
const viewsDir = path.join(__dirname, 'views');  
const layoutsDir = path.join(viewsDir, 'layouts');

app.engine('hbs', expressHandlebars({  
    defaultLayout: 'default',
    layoutsDir,
    extname: '.hbs'
}));

app.set('views', viewsDir);  
app.set('view engine', 'hbs');

// mount a main router
app.use('/', routes);

// to be brief, 404 and error handlers are omitted

module.exports = app;  

Do aplikace pak metodou use() zapojíme router a prvním parametrem specifikujeme jeho počáteční URL: /. Díky tomuto principu je možné aplikaci rozdělit na samostatné moduly a každému modulu nastavit vlastní počáteční url. Například /admin pro administraci, nebo /api pro aplikační rozhraní.

Funkce require() se v případě, že ji jako parametr předáte cestu k adresáři, pokusí načíst soubor index.js uvnitř adresáře. To je praktické, protože se tím zjednodušuje a zpřehledňuje načítání potřebných modulů.

/bin/www

Nakonec samotný spustitelný soubor. Abychom odlehčili aplikačnímu bootstrapu, webový server spustíme zde. Nejprve se z proměnné prostředí (env) pokusíme zjistit port, na kterém by aplikace měla běžet, a pokud takové nastavení neexistuje, nastavíme výchozí hodnotu, port 3000. V Node.js se často využívají proměnné prostředí ke konfiguraci aplikace, a jde o ideální způsob, jak aplikaci předat například hesla do databáze, nebo obecně aplikaci informovat, že běží na produkčním prostředí.

#!/usr/bin/env node

const app = require('../app');  
const http = require('http');

const server = http.createServer(app);

// fetch port from environment variable
const port = process.env.PORT || 3000;  
app.set('port', port);

// start server
server.listen(port);  

Přestože Express aplikace má vlastní metodu listen(), je vhodné si prostřednictvím modulu http vytvořit server a až na něm metodu listen() zavolat. Díky tomu pak můžete přímo naslouchat na události spojené s webserverem, jako jsou error a listening, které vás informují o okamžiku spuštění serveru, nebo eventuelních problémech a jejich příčinách. V příkladu použití Express.js na mém Githubu je k vidění příklad implementace.

Spouštíme první aplikaci

Pokud nezapomenete vytvořit šablony /views/index.hbs a /views/layouts/default.hbs, zbývá vám jen do souboru package.json vložit direktivu start:

{
    ...
    "scripts": {
      "start": "node --use-strict ./bin/www"
    },
    ...
}

Ke spuštění aplikace použijete příkaz npm start a v prohlížeči otevřete url http://localhost:3000 a hurá, vaše aplikace běží! Nejste-li si jistí, kam který kus kódu umístit, prohlédněte si hotový příklad Express.js na Githubu.

David Menger

Read more posts by this author.