Programování v Node.js

Node.js je prostředí JavaScriptu postavené na V8 (open source JavaScriptový engine od Google), které se používá k běhu serverových aplikací. Jeho výhodou je rychlost a možnost psát aplikace v JavaScriptu. Pro Node.js existuje velké množství modulů, kter lze snadno přidat do projektu. Mezi nejpopulárnější patří modul express, který umožňuje rychlý vývoj webových aplikací.

Instalace

Node.js se nachází v repozitáři Ubuntu 12.10 ve verzi 0.6.19, my si ale stáhneme zdrojové kódy té nejnovější z oficiálních stránek, tedy verzi 0.8.16: http://nodejs.org/dist/v0.8.16/node-v0.8.16.tar.gz. Nainstalujeme ho do systému pomocí standardních příkazů:

./configure
make
sudo make install

Je třeba mít nainstalovaný Python 2.6 nebo 2.7 a GNU Make 3.81 nebo novější. Společně s Node.js se instaluje i správce modulů npm. Oba programy budou v adresáři /usr/local/bin/.

Pozn.: Je možné stáhnout i zkompilovaný Node.js a neinstalovat ho do systému. Pak je vhodné udělat symbolické linky pro node a npm do adresáře /usr/local/bin/.

Vývojové prostředí

Bohužel, pro Node.js neexistuje vývojové prostředí, které by mi vyhovovalo. Plugin do Eclipse přidává jen možnost vytváření a spouštění projektů. Navíc nezobrazuje chyby v adresáři s moduly, což je příjemné. Každopádně si neumí poradit s doplňováním kódu, který je přidán pomocí require a také se mi nepodařilo zprovoznit doplňování pro JavaScriptové objekty.

O něco lepší je klon IntelliJ s názvem WebStorm. Podporuje přímo Node.js a až na varovné hlášky ohledně parametrů některých funkcí, se mi v něm vyvíjelo dobře. Doplňuje většinu kódu. Samotné prostředí je stejné, jako má IntelliJ, takže se v něm píše přijemně. Rychlost prostředí je podobná Eclipse.

Podporu JavaScriptu má také editor Sublime Text 2. Je velmi rychlý a má pokročilé funkce. Vytváření a editace kódu pro Node.js je v něm velmi příjemná. Při doplňování nabízí text, který už byl dříve napsán (nezáleží jestli před nebo za editovaným místem).

Osobně používám pro spouštění, správu projektu a zachytávání výstupů konzoli jako nejrychlejší a nejjednodušší nástroj. Její výhoda je v tom, že mi další okno nezakrývá/nezmenšuje celkový pohled na zdrojový kód.

První projekt

Jako ukázku funkčního kódu uvedu program, který použije modul express k vytvoření serveru na portu 8080 a při každém přístupu na adresu localhost:8080 vypíše na konzoli hlášku.

var express = require('express');
var app = express();

console.log('Server is running...');

app.get('/', function(req, res) {
  console.log('get request');
  res.send('hello');
});

app.listen(8080);

Dobrá praxe je vytvořit soubor package.json s informacemi o našem projektu. Pro nás je nejdůležitější definování závislosti modulu express. Základní obsah by mohl vypadat takto:

{
    "name":"hello-world",
    "version":"0.0.1",
    "private":true,
    "scripts":{
        "start":"node app"
    },

    "dependencies":{
        "express":"3.0.x"
    }
}

Nyní můžeme spustit příkaz pro stažení závislostí (ty se objeví v adresáři node_modules u našeho projektu) a samotné spuštění aplikace:

npm install
node app.js

Všimněme si, že pokud aplikaci spustíme a uděláme v ní nějaké změny, ty se neprojeví. Jsme nuceni restartovat celou aplikaci a je to nešikovné. Naštěstí existuje utilita supervisor, která dokáže hlídat, jestli se v projektu změnil nějaký soubor a v případě že ano, provede restart aplikace sama. Její použití je intuitivní:

supervisor app.js

Databáze a REST API

Pozn.: Tato kapitola je velmi inspirována článkem Jakuba Mrozka, který je publikován na serveru zdrojak.cz. Doporučuji přečíst celou sérii jeho článků, ve které programuje e-shop za použití Node.js, Monga a Angularu. Uvádím ji proto, aby zde existovalo kompletní, jednoduché a funkční REST API využívající databázi, které se dá zkopírovat a hned na něm stavět vlastní projekt.

Pro instalaci Monga stačí využít balíček mongodb z repozitáře. Příkazem mongo se spustí terminálový klient. Ukážeme si základní práci s ním:

use pokus
var product = {name: 'iPhone', url: 'iphone'};
db.products.insert(product);
db.products.find();

Nejdříve uděláme aktivní databázi pokus. Pak definujeme objekt a vložíme ho do databáze. Poslední příkaz vypíše všechny produkty z databáze.

Pro Node.js existuje modul mongoose, který umožňuje jednodušší práci s databází (podobně jako některé ORM frameworky). Dalším užitečným modulem je express-resource, který je vhodné použít pro budování REST API, protože přidává expressu metodu resource, která očekává controller s metodami index, show, create, update a destroy, které se mapují na zadané URL.

model/Page.js

var mongoose = require('mongoose');

var PageSchema = new mongoose.Schema({
  title: String,
  url: String
});

// Our static method findOneByUrl is called in app.js
PageSchema.statics.findOneByUrl = function(url, cb) {
  Model.findOne({url: url}, cb);
};

var Model = module.exports = mongoose.model('Page', PageSchema);

controller/Page.js

var PageModel = require('../models/Page');

// GET: /
exports.index = function(req, res) {
  PageModel.find(function(err, docs) {
    if (err) console.log(err);
    res.json(docs);
  });
};

// GET: /url
exports.show = function(req, res) {
  res.send(req.page);
};

// POST: / JSON: {"title":"První", "url":"prvni"}
exports.create = function(req, res) {
  var page = new PageModel();
  page.title = req.body.title;
  page.url = req.body.url;
  page.save(function(err, doc) {
    if (err) console.log(err);
    res.json(doc);
  });
};

// PUT: /url JSON: {"title":"První"}
exports.update = function(req, res) {
  req.page.title = req.body.title;
  req.page.save(function(err, doc) {
    if (err) console.log(err);
    res.json(docs);
  });
};

// DELETE: /url
exports.destroy = function(req, res) {
  req.page.remove(function(err, doc) {
    if (err) console.log(err);
    res.json(doc);
  });
};

app.js

require('express-resource');

var express = require('express');
var mongoose = require('mongoose');
var app = express();

console.log('Server is running...');

var PageController = require('./controllers/Page');
var PageModel = require('./models/Page');

// Connect to the database
mongoose.connect('mongodb://localhost/pokus', function(err) {
  if (err) console.log(err);
});

// Use body parser (required in controller)
app.use(express.bodyParser());

app.get('/', function(req, res) {
  res.send('hello');
});

app.resource('pages', PageController, { base: '/api/', load: PageModel.findOneByUrl });

app.listen(8080);

package.json

{
    "name":"application-name",
    "version":"0.0.1",
    "private":true,
    "scripts":{
        "start":"node app"
    },

    "dependencies":{
        "express":"3.0.x",
        "express-resource":"1.0.x",
        "mongoose":"3.3.x"
    }
}

Po přidání závislostí je třeba v adresáři projektu spustit následující příkaz, který stáhne potřebné závislosti do souboru node_modules.

npm install

Testování

Závěr

Na několika fórech jsem četl, že Node.js není vhodné pro větší projekty a už vůbec ne pro projekty komerční. Myslím, že tomu tak není a Node.js má své uplatnění. Je to sice mladý projekt, ale už teď pro něj existuje nepřeberné množství modulů, které lze snadno použít ve své aplikaci.

V budoucnu se chci ještě věnovat možnostem testování pro Node.js a vývojem řízeným testy (Test Driven Development), na což v tomto článku nezbylo místo.

Napsat komentář

Vaše emailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *