senäh

17senäh und so…

HTML/CSS/JS
13. Okt 2013
Kommentare: 0

Node.js

Kategorien: HTML/CSS/JS | 13. Okt 2013 | Kommentare: 0

Serie: Einführung in den MEAN Stack

In diesem Artikel erkläre ich euch was Node.js genau ist und welche besonderen Eigenschaften es hat. Außerdem programmieren wir in fünf Codezeilen einen funktionierenden Server!

Node.js (kurz Node) ist eine serverseitige Laufzeitumgebung für JavaScript basierend auf der V8 Engine von Google. Node nutzt ein eventbasiertes und nichtblockendes Eingabe-Ausgabe-Modell und eignet sich damit für schnelle und skalierbare Netzwerkapplikationen. Aber was bedeutet das in der Praxis?

Der Prozess beim Aufruf einer Webseite mit dem im ersten Artikel erwähnten LAMP Stack ist ungefähr folgender: Der Browser startet einen Request mit einer URL, welche beim Apache Server eintrifft. Abhängig von der URL ruft Apache verschiedene PHP-Skripte auf, welche einen Response – die eigentliche Webseite – aufbauen. Die PHP-Skripte können währenddessen Daten aus der MySQL-Datenbank abrufen, um den Response mit diesen Daten zu füllen. Sind alle PHP-Skripte abgearbeitet, wurde die Webseite vollständig ausgegeben. Erst jetzt können wieder neue Requests zu Responses von PHP umgewandelt werden.
Bei Node ist dies anders. Node übernimmt die Aufgaben von Apache und PHP gleichermaßen. Es nimmt einen Request entgegen und ruft entsprechende JavaScript-Skripte auf, um mit einem Response zu antworten. Dabei können Datenabfragen von Node an eine MongoDB-Datenbank (oder einer anderen beliebigen Datenbank) gestellt werden. Bereits jetzt kann Node anfangen neuen Requests abzuarbeiten, da die Abfrage der Datenbank eine gewisse Zeit in Anspruch nimmt. Diese Zeit bliebe beim LAMP Stack ungenutzt. Ist die Datenbankabfrage beendet, arbeitet Node wieder den ursprünglichen Request zu einem Response ab, sobald entsprechende Prozesszeit frei ist. Dieses Zurückspringen zu einem vorigen Requests wird über Callbacks gelöst, Funktionen, die ausgeführt werden, wenn ein bestimmtes Event (wie das Ende einer Datenbankabfrage) eintrifft.

Dies entspricht jedoch nicht exakt der Realität. Durch andere Threads bzw. Prozesse kann der LAMP Stack trotz einer laufenden Datenbankfrage weitere Requests zu Responses verarbeiten. Ihre Anzahl ist jedoch von der Hardware begrenzt und skalieren somit schlechter.

Node wurde von Ryan Dahl entwickelt, welcher die Verantwortung des Projekts mittlerweile an Isaac Schlueter abgegeben hat.

Im Kern ist Node ein C++ Projekt, dessen APIs jedoch über JavaScript gesteuert werden.

Diese Artikelserie soll vor allem auf praktischem Wege den MEAN Stack erklären. Deswegen wird im folgenden Beispiel bereits nach dieser kurzen Definition ein vollständiger HTTP-Server mit Node programmieren. Dafür genügen bereits wenige Zeilen Code:

var http = require('http');
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello World\n');
}).listen(1337, '127.0.0.1');

Speichert diesen Code in eine Datei namens server.js und startet dann mit folgendem Befehl den Node-Server (/pfad/zu muss dabei von euch mit dem echten Pfad zur server.js ersetzt werden):

$ node /pfad/zu/server.js

Wenn ihr nun in einen beliebigen Browser http://127.0.0.1:1337/ in die Adresszeile eintippt, so erhaltet ihr ein „Hello World“ zurück.

Der Node-Server funktioniert!

Mit einem ⌃C innerhalb des Terminals könnt ihr den Node-Server wieder beenden.

Was ist passiert? In der ersten Codezeile wird mit der Funktion require das Modul http aufgerufen. Das http Modul besitzt die Funktion createServer, welche wortwörtlich einen Server erstellen kann. Der Test im Browser hat es bewiesen! Die Funktion enthält einen Callback mit den zwei Parametern req und res, welche für Request und Response stehen. Der Callback wird bei jedem Request an http://127.0.0.1:1337/ aufgerufen. Das req-Objekt enthält bspw. Informationen über die URL, welche wir aber in diesem Beispiel noch nicht verwendet werden. Über das res-Objekt wird der Text „Hello World“ ausgegeben.

Übrigens: Bei jeder Codeänderung muss Node erneut gestartet werden, damit die Änderung wirksam wird! Dies wird in der nachfolgenden Beispielen nicht mehr ausdrücklich erwähnt und sollte deswegen im Kopf behalten werden.

Jeglicher Node-Code wird in Modulen basierend auf dem Standard CommonJS organisiert. http ist ein sogenanntes Core Modul, also ein Modul, welches mit Node selbst ausgeliefert wird. Alle Core Module und ihre APIs können unter http://nodejs.org/api/ nachgeschlagen werden. Bestandteil von CommonJS ist die Funktion require, welche das Laden von Modulen übernimmt. Da sich jeglicher Node-Code in Modulen befindet, können diese auch immer required werden. Ohne es zu wissen haben wir mit der Datei server.js unser erstes Node-Modul geschrieben, welches von anderen Modulen required werden kann. Dies können wir auch gleich mit einem weiteren Modul testen, welches wir in eine Datei require-server.js speichern:

var http = require('./server');

Die Datei require-server.js enthält nur eine Codezeile und muss im gleichen Ordner wie server.js liegen. Mit folgendem Befehl können die Datei in Node ausgeführt werden:

$ node /pfad/zu/require-server.js

Ruft ihr nun wieder http://127.0.0.1:1337/ im Browser auf, dann erhaltet ihr wie zuvor ein „Hello World“. Das ./ innerhalb von require zeigt, dass ein Modul im gleichen Ordner mit dem Dateinamen server geladen werden soll. Die Dateiendung .js kann weggelassen werden, da sie von Node automatisch angenommen wird.

Damit ihr aus diesem einfachen – und noch wenig brauchbaren – Server bald eine sinnvolle Applikation erstellen könnt, benötigen wir ein paar Frameworks, die uns bei der Entwicklung helfen. Wie ihr Frameworks (bzw. Node Module) einfach verwalten könnt, zeige ich euch im nächsten Artikel.

Autor: Pipo

...kommt ursprünglich aus der Designerecke, ist aber im Laufe seines Studiums in die Webentwicklung gestolpert. Kann sich seit dem nicht so richtig entscheiden wo er hingehört und wagt deswegen vielleicht die Flucht nach vorne in ein komplett neues Gebiet. Vielleicht Management? Niemand weiß es. Auch er nicht.