Open Source im professionellen Einsatz
Linux-Magazin 05/2013
1055

Mit Jade und Redis

Listing 13 zeigt die zugehörige Paketbeschreibung »project.js« . Das Beispiel hängt von Express, Redis und der Template-Engine Jade ab. Die abschließende Befehlsfolge »cd booking && npm install« installiert alle benötigten Module im Unterverzeichnis »node-modules« .

In Listing 14 findet sich der Quellcode der Beispielanwendung aus der Datei »app.js« . Die Zeilen 1 bis 4 binden die benötigten Module ein, Zeile 5 erzeugt das Express-Objekt »app« . Die Zeilen 7 bis 8 machen Angaben zur verwendeten Template-Engine Jade. Die Methode »use()« in den Zeilen 9 bis 18 bindet die Middleware ein.

Listing 14

Kern der Beispielanwendung

01 var express = require('express'),
02   routes = require('./routes'),
03   http = require('http'),
04   redis = require('redis'),
05   app = express();
06
07 app.set('views', __dirname + '/views');
08 app.set('view engine', 'jade');
09 app.use(express.static(__dirname + '/public'));
10 app.use(express.bodyParser());
11 app.use(function(req, res, next) {
12   redis.createClient().set('max', 10, function() {next();});
13 });
14 app.use(app.router);
15 app.use(function(err, req, res, next) {
16   console.log(err.stack);
17   res.send(500, '<h1>Internal Server Error</h1>');
18 });
19
20 app.get('/', routes.index);
21 app.post('/book', routes.book);
22 app.post('/checkin', routes.checkin);
23 app.post('/checkout', routes.checkout);
24 app.post('/reset', routes.reset);
25 app.listen(3003);

Listing 15

Verweis auf eine CSS-Datei

01 doctype 5
02 html
03  head
04   link(rel='stylesheet', href='/stylesheets/style.css')
05  body
06   #ticket
07     #symbol P
08     block content

Dabei ist die Reihenfolge des Aufrufs der Middleware wichtig: Die einzelnen Komponenten werden für alle HTTP-Anfragen nacheinander aufgerufen. Findet beispielsweise die Middleware aus Zeile 9 anhand der URL ein gleichnamiges Dokument im Verzeichnis »public« , so sendet sie dies und schließt das Bearbeiten der HTTP-Anfrage ab.

Das Parsen des Körpers der HTTP-Anfrage in Zeile 10 erfolgt nur für HTTP-Anfragen, zu deren URL Zeile 9 kein passendes Dokument gefunden hat. Zeile 12 speichert die Anzahl der Parkplätze zum Schlüssel »max« in Redis. Der Aufruf der Funktion »next()« ohne Wert (Abbildung 8) in der Callback-Funktion startet die nächste Middleware. Zeile 14 aktiviert die Behandlung von Routen.

Abbildung 8: Der Aufruf von next() ohne Wert geht zur nächsten Middleware über.

Die Zeilen 15 bis 18 legen eine Callback-Funktion für Fehler fest. Diese Funktion verwendet vier Parameter: Der erste übernimmt eine Fehlermeldung, der zweite die HTTP-Anfrage, der dritte die HTTP-Antwort, der vierte eine Referenz auf die Funktion »next()« . Die Callback-Funktion lässt sich mit »next()« und einem nicht leeren Parameter aufrufen, zum Beispiel mit »next('user error')« .

Die Methoden-Aufrufe in den Zeilen 20 bis 24 weisen dem Pfadanteil der aufgerufenen URL eine Callback-Funktion aus dem Objekt »routes« zu. Die Methoden-Namen korrespondieren mit der Methode der HTTP-Anfrage. Nur wenn Pfadanteil und Methode übereinstimmen, wird die Callback-Funktion aufgerufen. Mit »all()« statt »get()« oder »post()« lässt sich jede Methode erfassen. Die Routenbeschreibungen können auch reguläre Ausdrücke enthalten, beispielsweise passt »/\/\w +\/node/« auf die URLs »/v8/code« oder »/js/node« . Die Zeichenkette »'*'« steht für die Defaultroute.

Listing 16 zeigt die Callback-Funktionen für die Routen aus Listing 14, die in Listing 10 noch nicht enthalten waren. Die Funktion »index()« erzeugt in Zeile 2 durch Aufruf der in Zeile 10 implementierten Funktion »show()« die Startseite der Beispielanwendung. »show()« übernimmt im ersten Parameter das Objekt der HTTP-Antwort und im zweiten den Namen einer Jade-Vorlage. Show benutzt die in Listing 11 beschriebene Funktion »stats()« , um die Erzeugung des HTML-Dokuments aus dem Jade-Template mit den statistischen Daten des Parkhauses zu parametrisieren.

Listing 16

Exportieren

01 exports.index = function(req, res){
02   show(res, 'index');
03 };
04
05 exports.reset = function(req, res) {
06   db.del('open', 'checkedIn');
07   res.render('reset', par());
08 }
09
10 function show(res, tpl, err, code) {
11  stats(function(free, open, ckd) {
12   res.render(tpl, par(free, open, ckd, err, code));
13  });
14 }
15
16 function par(free, open, ckd, err, code) {
17   return {"code": code, "err": err, "free": free, "open": open, "ckd": ckd};
18 }

Die Methode »reset« in Zeile 5 löscht die Sets »open« und »checkedin« in Redis, bevor sie mit »render()« eine Bestätigung in HTML ausgibt. Die Methode »render()« wiederum erzeugt aus der Jade-Vorlage »reset« ein HTML-Dokument. Die Hilfsfunktion »par()« in Zeile 16 formatiert die statistischen Angaben zum Parkhaus zwecks Parametrisierung der Vorlage. Die Funktionen aus Listing 16 komplettieren also Listing 14. Der Quellcode ist in der Datei »routes/index.js« zu finden.

Jade-Vorlagen

Die Beispielanwendung verwendet Jade, um HTML-Dokumente zu erzeugen. Express speichert die Vorlagen in Dateien mit der Endung ».jade« im Unterverzeichnis »views« ab. Jade-Vorlagen sind in einer eigenen Sprache verfasst, die neben einer verkürzten Schreibweise von HTML-Markup auch Variablen, Schleifen und Verzweigungen umfasst.

Listing 17 zeigt eine Jade-Vorlage aus der Beispielanwendung. In Zeile 1 bindet die Direktive »extends« den Kopf des HTML-Dokuments aus der Vorlage »layout.jade« (siehe Listing 15) ein. Im Gegensatz zu einer einfachen Inklusion stellt sich die Vorlage durch »extends« als Erweiterung von »layout« dar.

Listing 17

Check-in am Parkhaus

01 extends layout
02
03 block content
04  #app
05   h3#free #{free} frei, #{open} gebucht und #{ckd} belegt
06   case err
07    when 1
08     h1 Checkin nicht möglich
09    default
10     h1 Sie sind eingecheckt
11     form(action="/checkout", method="post")
12      input(type="hidden", name="code", value=code)
13      input(type="submit", value="Checkout")
14   form(action="/", method="get")
15    input(type="submit", value="Erneut Buchen")
16   form(action="/reset", method="post")
17    input(type="submit", value="Zurücksetzen")

Ab Zeile 3 beginnt ein »content« -Bereich, die darauf folgende Zeile erzeugt einen »div« -Container mit dem Attributwert »app« für das Attribut »id« . Zeile 5 dereferenziert in dem »h3« -Element »free« die Werte der Variablen »free« , »open« und »ckd« ähnlich wie in Bash-Skripten.

Die Case-Anweisung ab Zeile 6 behandelt den Fehler in der Variablen »err« . Die Syntax von Jade vermeidet schließende Tags, Verschachtelungen zeichnet sie durch Einrückungen aus. Die Auszeichnung von Geschwister-Elementen beginnt stets in derselben Spalte, so wie in den Zeilen 10, 11, 12 oder 13.

Diesen Artikel als PDF kaufen

Express-Kauf als PDF

Umfang: 7 Heftseiten

Preis € 0,99
(inkl. 19% MwSt.)

Linux-Magazin kaufen

Einzelne Ausgabe
 
Abonnements
 
TABLET & SMARTPHONE APPS
Bald erhältlich
Get it on Google Play

Deutschland

Ähnliche Artikel

  • Bücher

    Die Bücherseite greift zwei aktuelle Trends auf: Das erste Werk behandelt die Anwendungsentwicklung mit dem Javascript-Server Node.js. Das zweite möchte Java- und C-Programmierer in die Arbeit mit mehreren Prozessoren und Nebenläufigkeit einführen.

  • Web RTC

    Das Protokoll Web RTC macht den Browser zur Kommunikationszentrale: Ganz ohne Plugins erledigt er Videochats oder Datei-Übertragungen über Peer-to-Peer-Verbindungen.

  • Node.js

    Die Javascript-basierte Programmierumgebung für Webentwicklung Node.js bändigt den Ressourcen-Hunger von Echtzeit-Webanwendungen wie Onlinespielen oder Chatservern. Dank eines ereignisorientierten Ansatzes kommt Node.js dabei mit einem Webserver-Thread pro Instanz aus.

  • Super-Nginx bündelt Redis, Drizzle und Lua

    Einer der Rails-Hauptentwickler paketiert den schnellen Webserver Nginx mit einer Reihe zukunftsträchtiger Technologien.

  • Node 7.0.0 unterstützt mehr ES6-Features und parst URLs standardkonform

    Node 7.0.0 ist erschienen. Die darin verwendete Version 5.4 von V8 deckt die ES6-Funktionen zu 98 Prozent ab. Zudem verbessert die Version den Umgang mit URLs.

comments powered by Disqus

Ausgabe 10/2017

Digitale Ausgabe: Preis € 6,40
(inkl. 19% MwSt.)

Artikelserien und interessante Workshops aus dem Magazin können Sie hier als Bundle erwerben.