REST-Webservices mit Node.js, Teil 2: Express als Anwendungsserver

Das Webframework Connect ist eine hilfreiche Grundlage für die Entwicklung von Node.js-Anwendungen. Darauf aufbauend gibt es das Framework Express, mit dem sich einfach REST-Webservices in Node.js entwickeln lassen.

In Pocket speichern vorlesen Druckansicht
Lesezeit: 17 Min.
Von
  • Golo Roden
Inhaltsverzeichnis

In einem früheren Artikel wurde Connect als hilfreiche Grundlage für die Entwicklung von Node.js-Anwendungen vorgestellt. Darauf aufbauend geht es nun um das Framework Express, mit dem sich einfach REST-Webservices in Node.js entwickeln lassen.

Das Webframework Express basiert intern auf Connect und erweitert dieses um zahlreiche fehlende Aspekte. Hierzu zählen unter anderem die für REST-Webservices wichtigen Routen, aber auch sonstige Hilfsmittel wie die einfache Verwaltung verschiedener Konfigurationen.

Ebenso wie die von Connect erfolgt die Installation von Express mit der Paketverwaltung von Node.js, npm, im lokalen Kontext der Webanwendung:

$ npm install express

Anschließend lässt sich Express durch einen Aufruf der require-Funktion importieren:

var express = require('express');

Die Instanziierung einer Webanwendung erfolgt bei Express auf die gleiche Art wie bei Connect:

var app = express();
http.createServer(app).listen(3000);

Auch bei Express ist es möglich, die erzeugte Anwendung ergänzend oder alternativ einem HTTPS-Server zu übergeben.

Damit die neu erzeugte Webanwendung auf eingehende Anfragen reagiert, ist ihr eigentlicher Code noch zu integrieren. Das geschieht durch den Aufruf der get-Funktion, die neben einem Callback eine Route entgegennimmt:

var app = express();
app.get('*', function (req, res) {
res.contentType('text/html');
res.send(200, 'Hallo Welt!');
});
http.createServer(app).listen(3000);

Dabei dient die Route * als Platzhalter und bewirkt, dass der angegebene Callback für jede eingehende Anfrage aufgerufen wird. Die Funktionen contentType und send sind Express-spezifische Erweiterungen des res-Objekts. Sie vereinen die Aufrufe von res.writeHead, res.write und res.end. Der Aufruf der contentType-Funktion könnte in diesem Beispiel streng genommen sogar entfallen, da die Funktion send im Fall einer Zeichenkette als zweitem Parameter standardmäßig den MIME-Type text/html an den Webbrowser sendet.

Da Express auf Connect basiert, lässt sich eine Express-Webanwendung wiederum um Module ergänzen. Dazu dient die aus Connect bekannte use-Funktion, die in Express allerdings in die configure-Funktion gekapselt wird:

var app = express();
app.configure(function () {
app.use(app.router);
});
app.get('*', function (req, res) {
[...]

Dabei dient das Modul app.router dazu, Routen wie * zu binden. Allerdings ist der Aufruf optional, da er spätestens bei der ersten Definition einer Route implizit ausgeführt wird. Interessanter als der Router ist daher die Fähigkeit von Express, sämtliche für Connect entwickelten Module weiterverwenden zu können. Das schließt insbesondere die in Connect enthaltenen ein. Damit für deren Verwendung aber nicht auch noch Connect zu importieren ist, reicht Express diese durch. So lassen sich alle in Connect integrierten Module nutzen, als ob sie in Express selbst enthalten wären:

var app = express(),
app.configure(function () {
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
});
app.get('*', function (req, res) {
[...]

Express kann weitere configure-Blöcke definieren, die in Abhängigkeit von der im Betriebssystem gesetzten Umgebungsvariablen NODE_ENV aktiviert werden. Hierfür übergibt man der configure-Funktion außer einem Callback einen oder mehrere Bezeichner. Während des Starts der Webanwendung vergleicht Express diese mit dem Wert der Umgebungsvariablen NODE_ENV. Bei Übereinstimmung wird der entsprechende configure-Block ausgeführt:

var app = express(),
app.configure(function () {
[...]
});
app.configure('development', function () {
[...]
});
app.configure('production', function () {
[...]
});
app.configure('development', 'production', function () {
[...]
});
app.get('*', function (req, res) {
[...]

Von den vier in diesem Beispiel verwendeten configure-Blöcken wird der erste stets ausgeführt. Die Ausführung der übrigen drei erfolgt kontextabhängig, wobei der letzte Block an zwei Werte gebunden wird.

Der Wert der Umgebungsvariablen NODE_ENV wird üblicherweise gesetzt, indem Node.js den Aufruf um die entsprechende Zuweisung ergänzt:

$ NODE_ENV=production node app.js

Diese Art des Aufrufs ist für den Produktivbetrieb einer Express-Webanwendung ausgesprochen wichtig, da zahlreiche Optimierungen von Express nur aktiviert werden, wenn die Umgebungsvariable NODE_ENV den Wert production aufweist.