Bachelorarbeit Node.js im Vergleich zu PHP
Inhalt
- 1 Einführung
- 2 Grundlagen
- 2.1 Web heute
- 2.2 JavaScript
- 2.3 Was ist Node.js?
- 2.4 Begriffsdefinition
- 2.4.1 Module
- 2.4.2 NPM-Node Package Manager
- 2.4.3 Middleware & Connect
- 2.4.4 Express
- 2.4.5 MongoDB
- 2.4.6 Twitter Bootstrap
- 2.5 Wesentlicher Unterschiede von Node.js zu PHP
- 2.5.1 Synchron & Asynchron
- 2.5.2 Programm-Ablauf
- 3 Anforderung und Analyse
- 3.1 Spezifikation
- 3.2 Analyse der Ausgangssituation
- 3.2.1 Unterstützende Technologien
- 3.2.2 Unterstützende Module
- 3.2.3 Datenbank
- 4 Implementierung
- 4.1 Entwicklungsumgebung
- 4.2 Aufbau des Node.js Projektes
- 4.3 Benutzeroberfläche
- 4.4 Implementierung der Beispiel-Applikation
- 4.4.1 Login
- 4.4.2 Kunde bearbeiten
- 4.4.3 Kundenübersicht
- 4.4.4 Kunde löschen
- 4.5 Überprüfen der Spezifikation
- 5 Vor- und Nachteile von Node.js
- 6 Wofür eignet sich Node.js
- 7 Schlussbetrachtung
- Abkürzungsverzeichnis
- Literaturverzeichnis
- Gedruckte Quellen
- Website
1 Einführung
1.1 Motivation
Das Internet ist heutzutage aus unserem Alltag kaum mehr wegzudenken. „Die Verbreitung
vollzieht sich in einer selbst für computerhistorische Verhältnisse atemberaubenden
Geschwindigkeit“. 5 Das rasant wachsende Internet bringt auch immer neue Webtechnologien
mit sich.
Seit 2009 taucht der Begriff Node.js in der IT-Fachpresse mit einer gewissen Regelmäßigkeit
auf und wird als „das nächste große Ding“ bezeichnet.
Mit dem Framework Node.js ist die Möglichkeit zur Entwicklung von serverseitigen
Webanwendungen in JavaScript gegeben. Aus diesem Grund kann ein Web-Entwickler die
Skriptsprache sowohl Client als auch serverseitig verwenden.
Um dynamische Webapplikationen entwickeln zu können, muss der Webentwickler mehrere
Technologien beherrschen.
Clientseitig kommt standardkonformes HTML und CSS zum Einsatz. In modernen
Applikationen werden diese Technologien von JavaScript und dadurch auch von Ajax ergänzt.
Mit einer traditionellen serverseitigen Skriptsprache wie beispielsweise PHP wird die Logik
implementiert. Zusätzlich wird noch eine Datenbanksprache zum Speichern, Abfragen,
Ändern und Löschen der Nutzdaten einer Webapplikation benötigt.
Mit dem Einsatz von Node.js erspart sich ein Entwickler nicht nur das Erlernen einer
zusätzlichen serverseitigen Programmiersprache, sondern springt auch gleichzeitig auf einen
neuen Hype der Webentwicklung auf. In der folgenden Grafik (siehe Abb. 1) werden die
derzeit verwendeten Technologien zur Erstellung einer Webanwendung der Firma AllBytes
dargestellt.
Abb. 1 Verwendete Technologien zur Webentwicklung bei der Firma AllBytes (HTML,PHP CSS, JavaScript MySql)
Die
Community um das serverseitige
JavaScript-Framework Node.js mag noch
verhältnismäßig klein sein, doch sie wächst stetig und gewinnt zunehmend an Professionalität.
Nicht nur durch die Integration von Node.js im Dezember 2013 in Microsofts
Entwicklungsumgebung Visual Studio ist zu erwarten, dass das Framework eine große Anzahl
an Entwicklern dazu gewinnen wird.
1.2 Ziel der Arbeit
Die Arbeit soll dem Leser einen Einblick in das Framework Node.js
bieten, dessen
grundsätzlichen Aufbau darstellen sowie die wesentlichen Unterschiede gegenüber einer
herkömmlichen serverseitigen Skriptsprache im Speziellen PHP aufzeigen.
Anhand der Implementierung einer Beispielanwendung, welche die typischen Anwendungsszenarien der herkömmlichen Webentwicklung beinhalten soll, soll geprüft
werden, ob Node.js die Werkzeuge mitbringt um eine traditionelle serverseitige Skriptsprache
wie PHP, ersetzen zu können. Genaueres zum Funktionsumfang der protypischen
Webanwendung wird in Kapitel 3.1 Spezifikation der Anforderungen beschrieben. Ebenso soll
diese Arbeit für zukünftige Node.js Interessenten eine Hilfestellung sein, ob und vor allem in
welchen Szenarien Node.js die richtige Technologie darstellt.
1.3 Aufbau der Arbeit
Der erste Teil der Arbeit gibt einen Überblick über das Framework Node.js. Es wird zu Beginn
auf den derzeitigen Stand der Webentwicklung eingegangen und die wichtigsten Begriffe
erklärt, die eine Voraussetzung für spätere Kapitel darstellen. Anschließend werden die
wesentlichen Unterschiede von Node.js zu PHP erläutert sowie eine Beispiel-Applikation in
Node.js umgesetzt. Zudem wird noch auf Gemeinsamkeiten der beiden Technologien
eingegangen.
Im anschließenden Hauptteil der Arbeit steht das Vorgehen bei der Entwicklung einer Node.js
Webanwendung im Vordergrund. Es wird zunächst auf die Anforderungen eingegangen,
welche die typischen Bestandteile einer modernen Webanwendung darstellen. Anschließend
werden unterstützende Technologien und Module beschrieben, bis hin zur Implementierung
der beispielhaften Node.js-Anwendung. Neben dem generellen Vorgehen zur Entwicklung
werden Vorschläge zur Struktur eines Projektes sowie zur Anwendungslogik gegeben.
Der letzte Teil geht auf die Vor- und Nachteile ein und bewertet, inwieweit sich Webentwickler
durch den Einsatz des Node.js Frameworks die zusätzliche Verwendung von weiteren
Technologien sparen können und somit sich nicht nur die Webentwicklung erleichtert sondern
auch vor allem der Einstieg. Der Schluss geht auf die Szenarien ein, wo sich die Entwicklung
mit Node.js besonders eignet, aber auch wann der Einsatz von herkömmlichen serverseitigen
Script-Sprachen wie PHP besser ist. Abgerundet wird die Arbeit durch mein persönliches Fazit,
sowie einen Ausblick und die Einschätzung über die weitere Verbreitung von Node.js.
1.4 Abgrenzung
Die Arbeit soll die Grundlagen von Node.js vermitteln sowie durch eine Beispielanwendung
einen Überblick verschaffen, ob und wie das Framework in der traditionellen Webanwendung
einsetzbar ist. Da die Implementierung mit Hilfe von integrierten Modulen erfolgt, werden
wichtige Grundlagen wie die Paketverwaltung (Node-Package-Manager) und der Umgang mit
Modulen auszugsweise beschrieben. Ein vollständiger Überblick kann aufgrund der
umfangreichen Thematik nicht gegeben werden. Aus demselben Grund werden zudem
Grundkenntnisse in JavaScript vorausgesetzt. Ferner werden bei der Beschreibung der Node-
Module lediglich Grundlagen und Grundprinzipien beschrieben.
Die Beispielanwendung wurde ausschließlich auf dem Linux basierten Betriebssystem Ubuntu
erstellt, weil dies die Entwicklungsumgebung der Firma AllBytes ist und sich „nahezu alle
verfügbaren Texte zu Node.js wie beispielsweise Blogeinträge, Anleitungen oder auch die
offizielle Dokumentation primär auf unixoide Betriebssysteme“ beziehen.
2 Grundlagen
2.1 Web heute
Das World Wide Web wächst rasant. Wie man aus der Grafik (siehe Abb. 2) entnehmen kann,
nutzen das Web im Jahr 2012 schon über 34% der Weltbevölkerung, während es um die
Jahrtausendwende nur etwas über 5% waren.
Abb. 2 Weltweite Nutzungsstatistik des Internets (http://www.internetworldstats.com/stats.htm, Zugriff: 31.01.2014)
Waren Übertragungsraten mit kabelgebundene Verbindungen im Jahr 2000 mit wenigen
Mbit/s noch eine Seltenheit, werden diese heute bereits im mobilen Bereich mit bestehenden
UMTS- und LTE-Netzen übertroffen. Die Initiative D21 und Huawei Technologies stellten
Anfang 2014 eine Studie zur mobilen Internetnutzung vor:
„Die mobile Nutzung des Internets gewinnt weiterhin an Bedeutung – sowohl mit Blick auf die
Anzahl der Endgeräte als auch auf die Nutzung. Aktuell besitzen 37 Prozent der in Deutschland
lebenden Bevölkerung ein Smartphone und 13 Prozent ein Tablet, 2012 waren es noch 24 bzw.
fünf Prozent. Der Anteil derjenigen, die das Internet über mobile Endgeräte nutzen, ist in
Deutschland im Vergleich zum Vorjahr um 13 Prozentpunkte auf 40 Prozent gestiegen. Mehr
als jeder zweite stationäre Internetnutzer (53 Prozent) geht heute bereits zusätzlich mobil ins
Netz – ein Zuwachs von 18 Prozentpunkten.“
Abb. 3 Mobile Endgeräte (https://www.tum.de/studium, Zugriff: 01.04.2014)
Das Internet ist allgegenwärtig und jederzeit Verfügbar. Gerade deswegen ist es sowohl für
private Haushalte als auch für große Konzerne ein nicht mehr wegzudenkender Bestandteil
geworden. Das Web trug zu einem grundlegenden Wandel des Kommunikationsverhaltens
bei, zu einer Modernisierung in vielen Bereichen sowie zur Entstehung neuer
Wirtschaftszweige.
Es werden immer mehr Anwendungen und Systeme ins Web ausgelagert, die von allen
Endgeräten abrufbar sein sollen. Responsive Design, die Bedienung durch Touchscreens,
gleichzeitig mit Freunden auf Facebook chatten und vom Web proaktiv über die neuesten
News informiert werden, sind nur einige der vielen Anforderungen, die moderne
Internetnutzer stellen.
Auf der Clientseite steigt JavaScript von der ehemals ungeliebten Sprache zur Lingua Franca 9
der modernen Webentwicklung auf. Derzeit typische Anwendungsgebiete sind die
Datenvalidierung von Formulareingaben, Ajax oder Werbebanner und Laufschriften
einzublenden. Zahlreiche moderne Webanwendungen wie beispielsweise das sozialeNetzwerk Twitter oder große Onlinewarenhäuser wie Amazon oder eBay wären ohne
Javascript undenkbar.
Zu serverseitigen Programmiersprachen und deren Verwendungshäufigkeit hat W3Techs eine
Marktanalyse durchgeführt.
Abb. 4 Marktanteil serverseitiger Programmiersprachen (http://phpmagazin.de/news/PHP-Marktanteil-auf-811-Prozent-
geklettert-167705, Zugriff: 31.01.2014)
Dabei ist PHP mit 81.1 Prozent die mit Abstand am häufigsten verwendete
Programmiersprache. JavaScript war mit einer Verwendungshäufigkeit von unter einem
Prozent weit abgeschlagen.
2.2 JavaScript
“The standard name for JavaScript is ECMAScript, because it is defined by the ECMA (an
international, private nonprofit standards organization). There are three well-known dialects
on the market: JavaScript (trademark of Sun, licensed now to the Mozilla Foundation),
ActionScript (trademark of Adobe), and JScript (trademark of Microsoft). At the base, they are
the same language, and everyone adds new behavior.”
Netscape veröffentlichte am 18. September 1995 mit der Vorversion des Netscape Navigators
2.0 einen Browser mit einer eingebetteten Skriptsprache namens LiveScript. Als Netscape und
Sun im Dezember eine Zusammenarbeit ankündigten um Java-Applets direkt mit LiveScript steuerbar zu machen, wurde die Sprache in JavaScript umbenannt. Auch Microsoft unterstützt
JavaScript seit der Version 3.0 des Internet-Explorers in Form von JScript.
ECMA (European Computer Manufacturers Association) entwickelte in Zusammenarbeit mit
Netscape ECMAScript (ECMA-262). Dies war ein wichtiger Schritt und sollte die
Grundelemente einer Skriptsprache standardisieren. Seit April ist ECMAScript eine ISO-Norm:
ISO/IEC 16262:1998 Informationtechnology – ECMAScript language specification.
„Skriptsprachen müssen als Interpreter-Sprachen in irgendeinen Interpreter implementiert
werden, damit sie zum Leben erwachen. Das ist beispielweise über einen skriptfähigen Browser
gewährleistet, wenn man ein Webskript in ein HTML-Gerüst einbindet. JavaScript ist so als eine
unmittelbare Ergänzung und Erweiterung zu HTML zu sehen und nur als eingebundener
Bestandteil eines HTML-Gerüsts zu verwenden. Webskripte werden als Klartext in eine
Webseite direkt notiert oder hinzugebunden und zur Laufzeit interpretiert.“
Folgendes JavaScript Quellcode-Beispiel gibt in einen JavaScript-fähigen Browser ein alert-
Fenster mit dem Titel meiner Bachelorarbeit „Node.js“ aus:
<html>
<body>
<script language=“JavaScript“>
alert(„Bachelorarbeit: Node.js!“);
</script>
</body>
<html>
Wie man aus dem Quellcode entnehmen kann, ist der JavaScript-Code in das HTML-Gerüst
eingebunden.
2.3 Was ist Node.js?
2009 entwickelte Ryan Dahl das Framework Node.js, das die serverseitige Implementierung
von JavaScript ermöglicht.
Abb. 5 Logo Node.js (https://nodejs.org/en/blog, Zugriff: 01.04.2014)
Node.js ist ein Framework und stellt keine vollständige Laufzeitumgebung dar, es basiert auf
Googles V8-Engine, diese kommt auch als JavaScript-Engine in Googles Browser Chrome zum
Einsatz. „Eine JavaScript-Anwendung läuft unabhängig von Anfragen der Clients auf dem
Server. Nach dem Start ist die Anwendung an einen bestimmten TCP-Port gebunden und
wartet auf Anfragen der Clients. Sobald eine Verbindung aufgebaut ist, besteht die
Möglichkeit, dass der Server aktiv mit dem Client kommuniziert“.
Daher nutzt Node.js nicht für jede eingehende Anfrage einen eigenen Thread, sondern
verarbeitet die Anfragen nacheinander auf einem Thread, eine sogenannte Non-Blocking I/O.
Auch aus diesem Grund kann Node.js mit einer viel größeren Anzahl von Anfragen fertig
werden. Das Thema Non-Blocking I/O und asynchrone Ausführung von Node.js Code wird in
Kapitel 2.4.1 Synchron & Asynchron näher beschrieben.
Einen besonderen Schwerpunkt legt Node.js auf die einfache und zugleich hohe Skalierbarkeit
von Webanwendungen. Websockets und Streaming sind Kernkonzepte in Node.js, um in der
modernen Webentwicklung dem ständig wachsenden Bedarf an zahlreichen gleichzeitigen
und dauerhaften Verbindungen gerecht zu werden.
Zudem ermöglicht der funktionale Ansatz von JavaScript und deren serverseitige Verwendung
in Node.js eine gute parallele Ausführung, d.h. eine Node.js Anwendung kann mehrere
Anweisungen, Berechnungen oder Befehle gleichzeitig ausführen. Mit wenigen Zeilen Code
lassen sich deshalb leistungsfähige und zeitgemäße Webanwendungen erstellen.
2.4 Begriffsdefinition
In den folgenden Abschnitten werden die wichtigsten Begriffe, die zum Verständis dieser Arbeit beitragen, näher erläutern.
2.4.1 Module
Module enthalten wichtige Funktionen, mit ihnen können die Fähigkeiten von Node.js
zusätzlich erweitert werden. Die Standardinstallation enthält bereits einige integrierte
Module, daneben besteht noch die Möglichkeit, Module aus dem Web herunterzuladen und
zu installieren, oder selber zu entwickeln. Ein Modul kann entweder eine Datei sein, dann
befindet sich sämtlicher Code genau in einer Datei oder bei komplexeren Modulen ein ganzes
Verzeichnis. Wird ein Modul erfolgreich installiert, meldet der Node Package Manager(siehe
Kapitel 2.3.2) die installierte Version des Moduls, die auch stets die aktuelle Version ist, sowie
den Pfad, in den das Modul installiert wurde. Die Abhängigkeiten zwischen einer Anwendung
und deren genutzten Modulen werden mithilfe des Namens eines Moduls, sowie der
Versionsnummer in der package.json Datei festgehalten.
Einbinde einer Datei als Modul:
var foo = require(./foo.js);
Einbinde eines Verzeichnisses als Modul:
var bar = require(./bar);
2.4.2 NPM-Node Package Manager
Die Paketverwaltung von Node.js nennt sich npm (Node Package Manager) und dient zur
Verwaltung von Modulen. Mit dem Node Package Manager kann man Module installieren,
aktualisieren, entfernen aber auch suchen.
Seit der Version 0.6.3 von Node.js entfällt die gesonderte Installation von npm, da die Packet
Verwaltung bereits in der Standardinstallation enthalten ist.
In der nächsten Grafik werden mit Hilfe des npm alle eingebundenen Module
eines Projektes in der Konsole aufgelistet. Es werden alle Abhängigkeiten, Modulnamen sowie
die Version angezeigt:
Abb. 6 Auslistung der verwendeten Module eines Node.js Projektes in der Konsole mit Hilfe des npm
2.4.3 Middleware & Connect
Connect ist ein Modul für Node.js Anwendungen, das ein Framework darstellt und Entwicklern
hilft Middleware in Anwendungen einzubauen. Auf Node.js bezogen, beutet Middleware eine
weitere Schicht zwischen dem Client und der Anwendungslogik.
„Die grundlegende Idee von Middleware im Allgemeinen und Connect im Speziellen ist, die
direkte Verbindung zwischen eingehenden Anfragen und der verarbeitenden Webanwendung
zu trennen, um Infrastrukturcode zwischen beiden Punkten einfügen zu können. Dazu dienen
der Middleware verschiedene Module, die unterschiedliche Aufgaben wahrnehmen,
beispielsweise Authentifizierung oder Internationalisierung. Diese schaltet die Middleware in
Reihe, sodass jede eingehende Anfrage zunächst die gesamte Kette von Modulen durchlaufen
muss, bevor sie sich schließlich von der eigentlichen Webanwendung verarbeiten lässt.
Sofern alle beteiligten Module die gleichen Schnittstellen bedienen, erlaubt dieses Prinzip das
für die Webanwendung transparente Einfügen beliebiger Module in beliebiger Reihenfolge
innerhalb der Middleware“
Abb. 7 Darstellung Middleware (http http://2.f.ix.de/developer/imgs/06/9/8/2/0/7/2/abb-09-01-707d3a53f603f55f.png,
Zugriff: 24.02.2014)
2.4.4 Express
Express ist ein flexibles Webframework, das viele Features zum Entwickeln von modernen
Webanwendungen beinhaltet. Das Framework kümmert sich um die primären Belange einer
Webanwendung wie das Routing von Anfragen, sowie um die sekundären Belange wie
Authentifizierung und Internationalisierung. Express baut auf das Middleware Framework
Connect auf, aus diesem Grund kann man auch Middleware in Express verwenden.
Die Installation von Express erfolt mit Hilfe von npm über die Konsole:
$ npm install express
Anschließend wird Express mit der require-Funktion in die Anwendung eingebunden:
var express = require('express');
2.4.5 MongoDB
Um Daten einer modernen Webanwendung sicher verwalten zu können, wird meist das lokale
Dateisystem oder eine Datenbank verwendet. Im Vergleich zu relationalen Datenbanken, die
ihren Fokus vor allem auf den Aspekt der Konsistenz legen, stellen NoSQL-Datenbanken eine
bessere Verfügbarkeit in den Vordergrund. MongoDB ist eine NoSQL-Datenbank, da diese
sehr einfach zu verwalten ist und eine JavaScript-fähige Schnittstelle besitzt, die nativ JSON
spricht, bietet sich die Verwendung in Verbindung mit Node.js an. MongoDB (von
„humongous“) ist eine dokumentenorientierte Datenbank. Ein Dokument ist gleichzusetzen
mit einem JSON-Objekt. MongoDB kann kostenlos für unixoide Betriebssysteme und Windows
gedownloadet werden.
Besonderheiten von MongoDB:
- Schemafreiheit:
Dokumente, die in MongoDB abgelegt werden, können eine beliebige Struktur haben - Indizierung:
MongoDb ermöglicht die Indizierung von Dokumenten auf sämtlichen Attributen - Replikation:
Zur Verteilung der Last beziehungsweise Ausfallsicherheit werden verschiedene Arten
von Replikation unterstützt - Sharding:
MMongoDB unterstützt das Sharding, das heißt, das Aufteilen großer Datenmengen über
mehrere Server hinweg - Map/Reduce:
Diese Art der Anfragen wird nativ von MongoDB unterstützt - GridFS:
- Es kann ein verteiltes Dateisystem aufgebaut werden, das beliebig große Dateien
speichern kann
2.4.6 Twitter Bootstrap
Bootstrap ist ein kostenloses CSS/HTML5-Framework, das von Twitter bereitgestellt wird.
Auf einer sehr umfangreichen Internetseite zu Bootstrap findet man den Downloadlink
sowie eine ausführliche Dokumentation zu allen Werkzeugen, die das Framework zur
Verfügung stellt.
„Twitter bezeichnet seinen Werkzeugkasten als Toolkit für den Entwicklungs-Kickstart und in
der Tat kümmern sich die Twitter-Developer um alle wesentlichen Aspekte beim Bau
moderner Web Apps und Websites. Dabei unterstützt es die gängigen Browser und verspricht
sogar Unterstützung für den IE ab Version 7“. Bootstrap ist ein modular aufgebautes
Framework und im Kern besteht es aus den LESS-Stylesheets, welche die Komponenten des
Toolkits implementieren.
Bootstrap wird standardmäßig mit einem zwölfspaltigen Grid-Layout ausgeliefert, das eine
standardmäßige Breite von 940 Pixel besitzt. Der Entwickler kann dem Layout durch
Verändern der CSS-Klassen seinen eigenen gewünschten Style hinzufügen. Zudem bietet das
Framework Responsive Webdesigns an, das heißt, es unterstützt verschiedene
Auflösungen und Gerätetypen:
- Mobiltelefon
- hoch- und querformatige Tablets,
- PCs mit geringer und hoher (Wildscreen-)Auflösung
Dabei passt sich die Breite der Spalten des Grid-Layouts automatisch der zur Verfügung stehenden Fensterbreite an.
2.5 Wesentliche Unterschiede von Node.js zu PHP
Es ist wichtig zu verstehen, dass es sich bei PHP um eine Scriptsprache handelt. Diese kann
zwar eine Website generieren, aber sie nicht selbst an den Besucher ausliefern. Darum wird
typischerweise ein Webserver zwischen den Besucher und PHP geschaltet. Ruft der Besucher
nun eine mit PHP betriebene Website auf, startet der Webserver das PHP-Script, welches
die angeforderte Seite dann generiert. Abschließend wird die fertig generierte Website an den
Besucher zurück gesendet.
Node.js ist hingegen keine Scriptsprache, sondern ein Framework, das wiederum die
Scriptsprache JavaScript enthält. Neben JavaScript besteht Node.js auch aus Modulen (siehe
2.3.1 Module), die man innerhalb der Scriptsprache verwenden kann. Eines dieser Module ist
für das HTTP-Protokoll und somit für Webseiten und Anwendungen zuständig.
In einer Node.js Anwendung ist die Andwendung selbst der Webserver.Eine zusätzliche Webserver-Software ist daher nicht erforderlich.
2.5.1 Synchron & Asynchron
Einen wesentlichen Unterschied zwischen PHP und Node.js stellt die Kommunikation dar. PHP
kommuniziert mit synchroner oder auch blockierender I/O, im Gegensatz dazu verwendet
Node.js die asynchrone oder auch die sogenannte Non-Blocking I/O.
Bei synchroner oder auch blockierender I/O bewirkt ein lesender Befehl, dass das Programm
so lange einfriert, bis die zu lesenden Daten verfügbar sind. Die CPU verbringt also die meiste
Zeit mit dem Warten auf Daten, aber nicht mit dem Rechnen, obwohl vielleicht noch einige
Berechnungen durchgeführt werden müssten. Damit ein Webserver trotz blockierender I/Oauch noch andere Anfragen beantworten kann, startet der Server einfach für jede Anfrage
einen eigenen Thread. Es wird viel Arbeitsspeicher mit Programmen belegt, die auf Daten
warten. Die Performance einer blockierender I/O wird durch die Anzahl der verfügbaren
Threads begrenzt.
Asynchrone Kommunikation dagegen verspricht eine bessere Nutzung der Ressourcen.
Node.js läuft normalerweise in einem Thread, der sich in einer endlos laufenden
Ereignisschleife, der Event-Loop, befindet 21 . Benötigt eine Anfrage aus einer Webanwendung
zum Beispiel Daten aus der Datenbank, schreibt oder liest von der Festplatte, so wird das im
Hintergrund ausgeführt. Die Event-Loop registriert das, das Programm läuft weiter und es
werden weitere Anfragen bearbeitet. Wenn beispielsweise die Anfrage auf die Datenbank
fertig ist, wird dies über eine Callback-Funktion an die Event-Loop gemeldet, welche die
nächsten Schritte zur Auslieferung der Daten anstößt.
Natürlich kann auch mit mehreren Prozessoren gearbeitet werden. „Sind mehrere Prozessoren vorhanden, können entsprechend viele Node.js-Prozesse gestartet werden. Die Kommunikation zwischen diesen muss, da es sich um getrennte Prozesse handelt, per
Internetprozesskommunikation erfolgen, also beispielweise über TCP/IP. Auf diese Weise
macht es für in Node.js entwickelte Webanwendungen keinen Unterschied, auf wie vielen
Maschinen sie ausgeführt werden: Die Kommunikation mit anderen Node.js Prozessen findet
immer auf die gleich Art statt“.
2.5.1.1 Beispiel Asynchron & Synchron
JavaScript Quellcode:
setTimeout(function(){
console.log(‘Welt‘);
}, 2000);
console.log(‘Hallo‘);
Startet man die Anwendung mit Node.js, wird zunächst Hallo ausgegeben und nach einer
Pause von zwei Sekunden der Text Welt. Das ist ein Beispiel für den synchronen, nicht
blockierenden Ablauf in Node.js. Die Ausführung wird nach der ersten Anweisung nicht
pausiert, sondern setzt sofort mit der nächsten Anweisung fort.
Wird dieser Codeblock beispielsweise mit PHP in einer LAMP Umgebung ausgeführt, dann
friert das System für zwei Sekunden ein, gibt zunächst Welt aus und fährt direkt im Anschluss
mit der Ausgabe von Hallo fort.
2.5.2 Programm-Ablauf
In PHP wird bei jedem Script-Ablauf genau eine Seite generiert. Das heißt, wird eine PHP-
Anwendung fünf Mal aufgerufen oder fünf Mal aktualisiert, so wird das PHP-Script auch 5 Mal
durchlaufen und ausgeführt.
„In Node.js wird eine Anwendung nur einmal gestartet, die Verbindung bleibt erhalten und
nimmt alle Anfragen in einem Ablauf entgegen. Dies ermöglicht es Daten zum Beispiel durch
Variablen zwischen mehreren Anfragen zu teilen, eine Variable wird nur einmal initialisiert.
Mit PHP ist das nicht möglich ist, da diese Variablen bei jeder Anfrage neu initialisiert werden.
Es müsste eine Datenbank oder ähnliches genutzt werden um Daten zwischen den einzelnen
Skript-Abläufen teilen und verwenden zu können.“
3 Anforderung und Analyse an die Beisppiel-Applikation
Nachdem alle Grundlagen und Vorrausetzungen, die zum Verständnis dieser Arbeit benötigt
werden, in den letzten Kapiteln beschrieben wurden, werden in diesem Kapitel, für die zu
implementierende prototypische Webanwendung der genaue Funktionsumfang definiert und
anschließend die Ausgangslage analysiert.
3.1 Spezifikation
Das Unternehmen AllBytes, unter deren Namen diese Arbeit entstand, hat für die hier
entwickelte Beispiel-Anwendung einen groben Funktionsumfang vorgegeben. Laut diesen
Vorgaben sollte die Beispiel-Anwendung alle typischen Bestandteile einer modernen
Webapplikation beinhalten. Folgende Hauptfunktionalitäten sollte die Applikation besitzen:
- Anmelden und Abmelden eines Benutzers. Beim Anmelden soll eine Session erstellt
und beim Abmelden des Users wieder zerstört werden - Es sollen Daten mit Hilfe der NoSQL-Datenbank MongoDB verwaltet werden
- Das Anlegen, Ändern und Löschen von Daten soll aus der Anwendung heraus
ermöglicht werden - Zusätzlich soll es eine Ansicht geben, die eine Übersicht über die gespeicherten Daten
der Datenbank gibt - Außerdem soll Twitter Bootstrap in die Applikation eingebunden werden und die
grafische Darstellung über das Framework erfolgen - Auf das lokale Dateisystem aus der Anwendung heraus zugreifen und Dateien
hochladen können
Außerdem war es Teil der Anforderung, dass die Webanwendung in den folgenden Browsern
funktionieren soll:
- Chrome Browser von Google
- Mozilla Firefox von Mozilla Foundation
- Internet Explorer von Microsoft
- Opera von Opera Software ASA
Da Node.js noch ein sehr junges Projekt ist, werden nur die aktuellsten Versionen der
jeweiligen Browser beachtet.
Hauptintention für das Unternehmen AllBytes ist hierbei, vor allem den Know-How-Zuwachs
im Bereich der serverseitigen JavaScript Entwicklung, sowie eine Vorreiterposition im Umgang
mit neuartigen Technologien einzunehmen. Es stehen in der Zukunft interessante und vor
allem moderne Projekte in Aussicht. Bei diesen Projekten sollen die Arbeit und die, dadurch
entstandenen Erfahrungen helfen:
- Die richtige Technologie auszuwählen
- Umsetzbarkeit von geplanten Technologien besser einschätzen zu können
- Herangehensweise an ein Node.js Projekt zu verdeutlichen
- Aufwanschätzung zu erleichtern
Um einen besseren Überblick über die funktionalen Anforderungen der Beispiel-Anwendung
zu gewinnen, werden diese in Abb. 8 mit Hilfe eines Use-Case-Diagramms veranschaulicht. Ein
Use-Case-Diagramm wird verwendet, um Funktionalitäten, die das zu entwickelnde System
bereitstellen soll, aus Anwendersicht zu beschreiben. Dabei gibt es im Allgemeinen vier
verschiedene Bestandteile: Systeme, Akteure, Anwendungsfälle und Beziehungen. In diesem
Fall ist der Benutzer der einzige Akteur. Die eigentliche Beispiel-Anwendung wird hier als
Node.js Applikation bezeichnet. Innerhalb der Systemgrenze der Node.js Applikation befinden
sich die Anwendungsfälle, welche durch Beziehungen miteinander verknüpft sind.
Abb. 8 Use-Case-Diagramm der Beispiel-Applikation
Bevor der User Zugriff auf die Anwendungsfälle „Übersicht ansehen“, „Kunde speichern“,
„Kunde bearbeiten“, „Kunde löschen“ oder „Kunde ansehen“ hat, muss er zunächst den
Anwendungsfall „Anmelden“ durchlaufen, da dieser eine Vorbedingung für alle anderen
Anwendungsfälle darstellt. Ist der User erst einmal angemeldet, kann er z. B. den
Anwendungsfall „Kunde speichern“ starten. Hat der User den Kunden erfolgreich gespeichert,
kann er alle gespeicherten Kunden mit dem Anwendungsfall „Übersicht ansehen“ betrachten.
Wenn keine Daten gespeichert sind, ist die Übersicht leer. Optional kann er die bereits gespeicherten Kunden mit dem Anwendungsfall „Kunde löschen“ löschen oder mit „Kunde
bearbeiten“ bearbeiten. Vor dem Beenden der Node.js Anwendung hat der User noch die
Option sich abzumelden.
Mit Hilfe des Use-Case-Diagramms entsteht ein Überblick über die Anforderungen, außerdem
sind Reihenfolgen im Ablauf des Programms festgelegt worden. Die fertige Spezifikation der
Beispiel-Applikation beschreibt ein Node.js-Programm, das Zugriff auf eine MongoDB
Datenbank und auf das lokale Dateisystem bietet. Mit dieser Anwendung ist es möglich
Kunden in der Datenbank zu speichern, diese zu löschen und zu bearbeiten. Voraussetzung
um Zugriff auf diese Funktionen zu haben, ist eine erfolgreiche Authentifizierung eines Users.
Die Use-Cases der Beispiel-Applikation sind ein ideales Anschauungsmittel, um die
Umsetzbarkeit einer modernen Webanwendung mit Node.js zu überprüfen und darzustellen.
3.2 Analyse der Ausgangsituation
Vor Beginn der Entwicklung der Beispiel-Applikation liegt es nahe, nach Diensten und
Technologien zu recherchieren, die das Entwickeln von Webanwendungen unterstützen und
erleichtern.
3.2.1 Unterstützende Node.js Technologien
Twitter Bootstrap ist ein HTML5/CSS Framework (siehe Kapitel 2.3.6), das die Entwicklung der
GUI erheblich erleichtern soll. Mit Bootstrap können sehr anschauliche und aufwendige
HTML-Templates erstellt werden. Es gibt auch schon vorgefertigte Open-Source-Templates,
die zur Verwendung bereitgestellt werden.
Um eine Node.js-Anwendung wirklich produktiv betreiben zu können, empfiehlt sich die
Verwendung eines bestehenden Webservers als Reverse Proxy an. Ansonsten kann nur eine
einzige Anwendung auf Port 80 gebunden werden. Ein bestehender Webserver ist auf die
Verarbeitung von Anfragen für verschiedene Anwendungen ausgelegt und bringt die Analyse
des Hostreaders bereits von Haus aus mit. Ein Hostreader ermittelt aus einem Request,
welche Anfrage für welche Anwendung bestimmt ist. „Um die hochskalierbare Ausführung von
Node.js nicht durch den Einsatz eines unpassenden Webservers zu beeinträchtigen, empfiehlt sich ein Webserver, der die gleiche Art der Skalierung wie Node.js nutzt. Ein solcher steht
beispielsweise mit Nginx zur Verfügung, der kostenlos als Open Source entwickelt wird und
unter anderem für den Betrieb von GitHub und WordPress eingesetzt wird.“ Nginx baut auch
auf eine asynchrone und ereignisorientierte Architektur.
3.2.2 Unterstützende Node.js Module
Außerdem sollte noch klar gestellt werden, welche Module die passenden Funktionen zur
Entwicklung moderner Webanwendungen mitbringen und somit ins Projekt eingebunden
werden sollten. Auf die wichtigsten Module soll im Folgenden, in einem kurzen Überblick,
eingegangen werden. Das http-Modul erhält einen extra Überpunkt, da es das fundamentalste
Modul für eine Webanwendung ist. Für die anderen Module findet man eine ausführliche
Beschreibung in der Dokumentation von Node.js. Ist ein Modul (siehe Kapitel 2.3.1) von
weiteren abhängig, löst npm (siehe Kapitel 2.3.2) die Abhängigkeiten automatisch auf und
installiert auch diese Module.
3.2.2.1 Das http-Modul
Hypertext Transfer Protocol (HTTP) ist ein Protokoll, das für die Kommunikation über das
Internet zuständig ist. Mit jeder Anfrage und Antwort wird ein HTTP-Header gesendet, der
verschiedene Informationen enthält. Beispielweise Status-Code, Datum und den Type of
content. Das http-Modul enthält Funktionen zum Implementieren von Webservern und
Webclients.Hier ein Beispiel, wie ein Webserver in Node.js implementiert wird:
var http = require(‘http‘);
http.createServer(function(req,res){
req.end(‘Hallo Welt‘);
});.listen(3000,‘127.0.0.1‘);
- In der ersten Zeile wird das http-Modul mit der bereits bekannten require Funktion in
das Projekt geladen, um die Funktionen und Objekte des Moduls nutzen zu können.
Diese werden in der Variablen „http“ gespeichert. - In Zeile 2 wird die Funktion des Moduls createServer aufgerufen und ein Webserver –
objekt erzeugt. - Der Inhalt der anonymen Callback-Funktion sagt, was der erzeugte Webserver machen
soll, wenn eine Anfrage eintrifft. Über die beiden Parameter req und res erhält man
Zugriff auf die zugrunde liegende Anfrage und die dazugehörige Antwort. In diesem
Fall wird „Hallo Welt“ zurückgegeben und die Verbindung beendet. - In der vierten Zeile wird eine weitere Funktion „listen“ aufgerufen. Dieser Funktion
wird der Port und Host übergeben.
Der Webserver des Codebeispiels kann
unter der Adresse http://127.0.0.1:3000
aufgerufen werden.
Abb. 9 Bildschirmfoto Beispiel des Webservers Hallo Welt
3.2.2.2 Weitere unterstützende Module
- https-Modul: Dieses Modul hat die gleiche Funktionalität wie das http-Modul,
allerdings auf Basis des https-Protokolls - url-Modul: Das url-Modul verfügt über Funktionen zum Analysieren und Formatieren
von URLs. Kann eine URL in ein Objekt auflösen, in dem Hostname, Port und Pfad
getrennt aufgeschlüsselt sind - fs-Modul: Enthält Funktionen, die Zugriff auf das lokale Dateisystem bieten. Es gibt die
üblichen Verzeichnisoperationen wie Erzeugen, Umbenennen, Verschieben und
Löschen, aber auch Funktionen und Dateien lesen und schreiben zu können - express-Modul: Express ist ein flexibles Webframework (siehe Kapitel 2.3.4)
- stylus-Modul: Das stylus-Modul muss per Hand in Express registriert werden, es
erzeugt statische CSS-Dateien, die dann in die Anwendung eingebunden werden - mongoskin-Modul: Das Modul mongoskin orientiert sich an der nativen Schnittstelle
von MongoDB und ist zugleich einfach zu verwenden. Mit mongoskin kann man z.B.
eine Verbindung aus der Anwendung heraus zur MongoDB Datenbank aufbauen - passport-Modul: passport ist ein Modul für Express, das sich um die Authentifizierung von Benutzern kümmert. Es können auch zahlreiche verschiedene Authentifizierungsanbieter, wie Twitter und Facebook integriert werden. Dieses
Modul bring auch Funktionen zur Erstellung von Sessions mit - moment-Modul: Dieses Modul verbessert den Umgang mit Datums- und Zeitwerten in
JavaScript. Außerdem kann Moment.js direkt im Browser verwendet werden - node-force-domain-Modul: node-force-domain ist eine Middleware für Connect und
Express, das alle Anfragen auf den Webserver auf eine Standartdomain umleiten
kann
Die unterstützenden Module wurden aus dem Buch „Node.js & Co.“ entnommen.
3.2.3 Datenbank
Mit Node.js können sowohl NoSQL-Datenbanken, aber auch klassische relationale
Datenbanken angesprochen werden. Allerdings verfügen die meisten relationalen
Datenbanken über keine native JavaScript Schnittstelle. Das heißt, man braucht zusätzlich
noch eine Datenbanksprache um mit der Datenbank kommunizieren zu können. Ob eine
relationale Datenbank mit Node.js angesprochen werden kann, liegt an der Verfügbarkeit
eines entsprechenden Moduls. Welche Datenbank letztendlich zum Einsatz kommt, sollte
anhand der individuellen Anforderungen an eine Webapplikation entschieden werden.
Relationale Datenbanken:
- MySQL
- PostgresSQL
- Oracle
- Microsoft SQLServer
- SQLite
NoSQL
- Cassandra
- Redis
- Memcached
- MongoDB
- Hadoop
Aufgeführte Datenbanken wurden aus dem Buch „Sams Teach Yourself Node.js“ 30
entnommen.
In der Beispiel-Applikation ist die Wahl auf MongoDB gefallen, da MongoDB (siehe Kapitel
2.3.5) eine JavaScript-Schnittstelle besitzt und somit nativ JSON spricht. Außerdem erspart
man sich durch den Einsatz von MongoDB, die bereits angesprochene, zusätzliche
Datenbanksprache.
3.2.3.1 Datentausch mit JSON
Die JavaScript Object Notation, kurz JSON, ist ein kompaktes Datenformat zum Zweck des
Datenaustauschs zwischen Anwendungen. JSON ist unabhängig von der Programmiersprache,
es existieren Parser in allen verbreiteten Sprachen, wie beispielsweise PHP und Java. Ein
weiterer Vorteil dieses kompakten Datenformats ist die leichte Lesbarkeit für Mensch und
Maschine. Es können Daten in Key-Value Paaren, aber auch Listen von Objekten, beliebig
verschachtelt, gespeichert werden. Die folgende Abbildung (siehe Abb. 10) zeigt die
Konstruktionsvorschrift eins JSON-Objekts.
„Ein Objekt ist eine ungeordnete Menge von Name/Wert Paaren. Ein Objekt beginnt mit {
(geschwungene Klammer auf) und endet mit } (geschwungene Klammer zu). Jedem Namen folgt ein : (Doppelpunkt) gefolgt vom Wert und die einzelnen Name/Wert Paare werden durch
, (Komma) voneinander getrennt.”
Abb. 10 Konstruktionsvorschrift JSON-Objekt (http://json.org, Zugriff:17.03.2014)
Folgendes Beispiel ist ein mit der obigen Konstruktionsvorschrift erzeugtes Objekt im JSON-
Format. Das Objekt stellt eine Firma dar:
{
‘Firmenname‘ : ‘AllBytes‘,
‘Gründungsdatum‘ : ‘2006‘,
‘Mitarbeiteranzahl‘ : ‘5‘,
‘Inhaber‘ : ‘Stanzl Alexander‘
}
4 Implementierung
In diesem Kapitel wird die Implementierung der Beispiel-Applikation erläutert. Die wichtigsten
Funktionen und Abläufe des Programms werden beschrieben und deren Implementierung
anhand von Quelltextausschnitten erörtert. Es werden ausschließlich Ausschnitte gezeigt, da
aufgrund des Umfangs nicht auf alle Details eingegangen werden kann. Die komplette
Implementierung, d.h. die vollständigen Methoden und deren Beschreibungen, kann im
Quellcode der Beispiel-Applikation auf der beiliegenden CD entnommen werden.
Zusätzlich werden Screenshots der Anwendung gezeigt, um dem Leser einen besseren
Überblick sowie ein besseres Verständnis der Programmelemente zu vermitteln.
4.1 Entwicklungsumgebung
Um mit der Entwicklung eines Node.js Projektes beginnen zu können, muss zunächst eine
geeignete Entwicklungsumgebung eingerichtet werden. Die Ursprünge von Node.js liegen im
unixoiden Umfeld, doch seit der Version 0.6.0 steht das Framework auch in einer nativen
Windows portierten Version zur Verfügung. 33 Diese Beispiel-Applikation wird ausschließlich in
Ubuntu entwickelt und als IDE wird NetBeans verwendet. Die wichtigste Voraussetzung um
mit der Entwicklung beginnen zu können, ist der Download und die Installation von Node.js.
Die Werkzeuge von Node.js basieren auf Python, darum muss das Packet python installiert
werden. Zusätzlich braucht man für eine moderne Webanwendung noch das Packet libssl-dev,
das für die Verschlüsselung von http-Datenströmen verantwortlich ist. Um diese Pakete auf
Ubuntu zu installieren genügen folgende Zeilen auf der Konsole:
$ sudo apt-get install phyton
$ sudo apt-get install libssl-dev
Anschließend kann der Quelltext von Node.js in Form einer tar.gz-Datei aus dem Web 34
heruntergeladen werden. Die Datei wird nun noch entpackt und in das neu erzeugte
Verzeichnis gewechselt:
$ tar zxf node-v0.10.26.tar.gz
$ cd node-v0.10.26
Die folgenden Schritte entsprechen dem üblichen Vorgehen unter Linux:
$ ./configure
$ make
$ sudo make install
Außerdem sollte der Pfad der ausführbaren Node-Anwendung im System mit folgendem
Befehl bekannt gemacht werden. Node.js ist danach einsatzbereit.
$ export PATH=$PATH:/opt/node/bin
Die Installationsanweisungen wurden aus dem Buch „Node.js &Co.“ entnommen.
4.2 Aufbau des Node.js Projektes
Zunächst muss ein neues Projekt in der IDE NetBeans angelegt werden. In der Beispiel-
Applikation wurde als Projekttyp HTML5 festgelegt. Bei der NetBeans Entwicklungsumgebung
ist es erforderlich, die üblichen Projektinhalte einer Node.js Anwendung per Hand
einzurichten. Folgende Abbildung (siehe Abb. 11) zeigt die Projektmappe der Beispiel-
Applikation.
Abb. 11 Projektmappe der Beispiel-Applikation
Alle Module, die im Projekt enthalten sind und installiert wurden, befinden sich im Ordner
node_modules. Außerdem werden die Module noch in der package.json Datei aufgelistet
(siehe Kapitel 2.3.1 Module). Im public-Ordner befinden sich sämtliche CSS- sowie alle JS-
Dateien, die ins Projekt eingebunden werden. In der Beispiel-Applikation kann ein Foto eines
Kunden hochgeladen werden, diese Fotos werden im Ordner uploads gespeichert. In der
index.js Datei im Ordner routes werden die Actions der einzelnen Routen geschrieben. Zum
Beispiel werden in den Actions Formulardaten verarbeitet. Sämtliche Views, die es in dem
Projekt gibt, werden mit der Dateiendung .html im Ordner views angelegt und gespeichert. Das in JSON formulierte Schema eines Objekts, das in der Datenbank verwaltet wird, wird in
der db.js Datei festgehalten. Außerdem wird in der Datei die Verbindung zur MongoDB
hergestellt.
Die Node.js Anwendung ist das Script, das gerade ausgeführt wird. In der Beispiel-Applikation,
ist das Start-Script die Datei app.js. Um die Anwendung zu starten, muss hinter dem Befehl in
der Konsole noch der Skriptdateiname als Parameter übergeben werden.
$ node app.js
4.3 Benutzeroberfläche
Im Kapitel 4.3 wird die Benutzeroberfläche der Beispiel-Applikation dargestellt. Wegen des
Umfangs der Anwendung werden kurz die zwei komplexesten Views dargestellt. Anhand von
Bildschirmfotos wird sowohl die GUI, als auch der HMTL-Code erläutert. Alle HTML-Templates
der Beispiel-Applikation können auf der beiliegenden CD betrachtet werden. Die Oberfläche
der Anwendung ist mit Twitter Bootstrap gemäß der Spezifikation erarbeitet worden. Da aber
jegliche Angaben bezüglich des Oberflächendesigns fehlten, ist die Beispiel-Applikation so
gestaltet worden, wie es für die Umsetzung der geplanten Funktionen am Sinnvollsten
erschien.
Nach dem erfolgreichen Login werden alle Kunden, die in der Datenbank gespeichert sind,
angezeigt (siehe Abb.12). Es werden nur die wichtigsten Daten auf der Startseite dargestellt.
Die Codestruktur (siehe Abb. 13) zeigt, wie für jedes Kundenelement der gleiche HTML-Code
erzeugt wird.
Abb. 12 View Kundenübersicht
Abb. 13 Ausschnitt des Quellcodes zur View Kundenübersicht
Die Abb. 13 ist ein Ausschnitt des Quellcodes zur Kundenübersicht. Die einzelnen
Kundenobjekte befinden sich in dem Array customers, das von der Action an die View
übergeben wurde. Variablen können mit dem Schema <%= Variablenname %> ausgegeben
werden. Entgegen der üblichen Praxis, JavaScript-Code in „<script></script>“-Tags
auszugeben, wird im View-Template der JavaScript-Code von <% und %> umschlossen. Über
die Kontrollstruktur forEach wird so der HTML-Block für jeden Kunden einmal erzeugt.
Wie man aus Zeile 4 der Abb. 13 entnehmen kann, ist jedes Kundenelement ein Link. Dieser
Link führt zur viewCustomer, dort werden mehr Detailinformationen eines Kunden dargestellt.
Um die richtigen Daten aus der Datenbank zu laden, wird die _id in der Route angehängt.
Da sich Twitter Bootstrap auch um das Responsive-Design kümmert, kann die Anwendung
sowohl in einem Browser auf dem Desktop, als auch im Browser eines mobilen Endgeräts
aufgerufen und benutzt werden. Es muss keine Zeile des Quellcodes für die Darstellung
geändert werden.
Abb. 14 Darstellung der Kundenübersicht in einem mobilen Endgerät
Die customerView ist die zweite View, die ich näher darstellen werde. Wie schon erwähnt,
werden dort die Detailinformationen eines Kunden angezeigt, des Weiteren können die Daten
eines Kunden bearbeitet werden, sowie ein Kundenobjekt aus der Datenbank gelöscht
werden.
Abb. 15 customerView – Darstellung der Kundendetails
Dieses Formular wird mit den zu übergebenden Kundendaten gefüllt. Fehlen Informationen
zu einem Feld, bleibt dieses leer. Die Daten des Kunden können durch Ändern des Inhalts der
Formulardaten aktualisiert werden. Auf der rechten Seite der Abb. 15 befindet sich das
Formularfeld für den Fotoupload, bleibt dieses beim Absenden des Formulars leer, ändert sich
das Foto des Kunden nicht. Standardmäßig wird das dargestellte Bild angezeigt.
Der folgende Quellcode (siehe Abb. 16) zeigt einen Ausschnitt des Formulars. Über die Route
/update/<%= customer._id %>
werden die Formulardaten an die Action update übermittelt.
Abb. 16 Ausschnitt des Quellcodes zur viewCustomer
4.4 Implementierung der Beispiel-Applikation
Aufbauend auf die Benutzeroberfläche, die in Kapitel 4.3 dargestellt wurde, wird hier die
Anwendungslogik durch Quelltextausschnitte zu den einzelnen Anwendungsfällen der
Beispiel-Applikation näher erläutert. Zu den wichtigsten Anwendungsfällen zählen „Login“,
„Kundenübersicht“, „Kunde anlegen“, „Kunde bearbeiten“, und „Kunde löschen“ (vgl.
Anwendungsfalldiagramm, Kapitel 3.1). Da die Anwendungsfälle „Kunde bearbeiten“ und
„Kunde anlegen“ sehr ähnlich sind, wird nur einer der beiden, nämlich „Kunde bearbeiten“,
näher dargestellt.
4.4.1 Login
Die Authentifizierung erfolgt über ein Formular der Beispiel-Applikation, als Anmeldedaten
werden Username und Passwort gefordert. Ein passendes Modul für Express, das diese
klassische Authentifizierung durch Benutzername und Passwort unterstützt heißt passport.
Passport bringt die benötigen Funktionen mit sich, außerdem können mit diesem Modul unter
anderem auch Facebook und Twitter als Anmeldeoption in eine Webanwendung eingebaut
werden. Dieses Vorgehen der Authentifizierung wird von passport auch als Local Strategy
bezeichnet, d.h. es muss noch eine weiteres Modul passport-local installiert und in die
Anwendung eingebunden werden. Die Verwendung dieser Strategie gestaltet sich einfach,
zum einen muss die Strategie konfiguriert werden, zum anderen muss die Anmeldeseite auf
die Strategie verweisen.
Damit nicht jede eingehende Anfrage an die Anwendung authentifiziert wird, soll der User
solange angemeldet bleiben, bis er sich wieder aus der Anwendung abmeldet. Dies geschieht
in Webanwendungen mit Hilfe einer Session, in dieser Session wird die Authentifizierung des
Users gespeichert.
Wichtig ist, dass das Modul passport sowie die Session initialisiert werden. Außerdem muss
noch passport-local importiert werden. Dies wird durch folgenden Codeblock sowie durch den
Aufruf folgender Funktionen in Express gemacht:
var passport = require(‘passport‘);
var LocalStrategy = require(‘passport-local‘).Strategy;
app.use(passport.initialize());
app.use(passport.session());
Zudem müssen noch die Funktionen serializeUser und deserializeUser in der Beispiel-
Applikation implementiert werden. Diese Funktionen dienen zum Speichern bzw. zum
Wiederherstellen des Users aus der Session.
Wird das Login-Formular abgeschickt, wird folgender Quellcode (siehe Abb. 14) abgearbeitet:
Abb. 17 Quellcodeausschnitt – POST-Login Route
Diese Route (siehe Abb. 17) nimmt die Daten des Login-Formulars nach der POST-Anfrage
entgegen und führt daraufhin die Authentifizierung durch. Dabei hilft die Funktion
authenticate, die vom Modul passport bereitgestellt wird.
Abb. 18 Quellcodeausschnitt – Passport Local Strategy
Mit der Funktion findOne in der Zeile 2 der Abb. 18 wird gecheckt, ob sich ein User mit diesem
Usernamen in der Datenbank befindet. Wenn ein User gefunden wurde, wird mit der Funktion
comparePassword (siehe Abb. 18 Zeile 5) das eingegebene Passwort mit dem Passwort des
Users aus der Datenbank vergliche. Stimmen die Passwörter überein, wird eine Session
erstellt und der User auf die Indexseite der Beispiel-Anwendung weitergeleitet, User
erfolgreich angemeldet. Stimmen Username oder Password nicht mit den Daten aus der
Datenbank überein, wird auf die Login-Seite weitergeleitet und es wird die dementsprechende
Fehlermeldung ausgeworfen.
4.4.2 Kunde bearbeiten
Wie in der Spezifikation vorgegeben, muss der User erfolgreich in der Beispiel-Applikation
eingeloggt sein, um einen neuen Kunden bearbeiten zu können. Die Funktion
ensureAuthenticated (siehe Abb. 20) überprüft beim Aufruf der Route (siehe Abb. 19), ob der
User authentifiziert ist. Falls keine gültige Session vorhanden ist, wird der User auf das
viewCustomer-Template weitergeleitet.
Abb. 19 Quellcodeausschnitt, Routing auf die create-Customer
Abb. 20 Quellcodeausschnitt, Funktion ensureAuthenticated
Wird das Formular, in dem die Kundendaten enthalten sind abgesendet, werden die Daten
eines Kunden aktualisiert. In Abb. 21 wird dargestellt, wie aus einem POST-Request die Daten
extrahiert und in das Customer-Objekt geschrieben werden. Anschließend wird der Kunde mit
der entsprechenden ID in der Datenbank geupdatet.
Abb. 21 Quellcodeausschnitt, Update eines Customer-Objekts
In der Variablen picture (siehe Abb.21) ist der Pfad des geuploadeten Bildes zu dem Kunden.
Ist der überarbeitete Kunde erfolgreich in der Datenbank gespeichert wird der User auf die
Indexseite „Kundenübersicht“ weitergeleitet.
4.4.2 Kundenübersicht
Um alle Kunden auf der Indexseite darstellen zu können, müssen diese erst aus der Datenbank
geladen werden. Wie schon im Anwendungsfall „Kunde bearbeiten“ ist Voraussetzung, dass
der User Authentifiziert ist. Das Herausladen der Daten aus der DB wird im folgenden
Quellcode-Ausschnitt (siehe Abb. 22) dargestellt.
Abb. 22 Quellcodeausschnitt, Laden der Kunden aus der Datenbank
Mit der Funktion render, wird das Array customers, indem sich alle Kunden befinden an die
View übergeben. Diese Funktion hat drei Übergabeparameter:
- Der Name der View, an das die Variable übergeben werden soll
- Optional kann ein Title an die View übergeben werden
- Die zu übergebende Variable, in diesem Fall das Array customers
In Abb. 12 (siehe Kapital 4.3 Benutzeroberfläche) wird dargestellt, wie die Kunden aus dem
Array in der View dargestellt werden.
4.4.4 Kunde löschen
Ein weiterer Anwendungsfall der Beispiel-Applikation ist „Kunde löschen“. Wie man aus der
Spezifikation entnehmen kann, ist auch bei diesem Anwendungsfall eine Authentifizierung
notwendig.
Wird in der Detailansicht eines Kunden auf den Link Delete gedrückt, wird die ID des aktuell
betrachteten Kunden an die Action übergeben.
Abb. 23 Quellcodeausschnitt, Kunde aus Datenbank löschen
Wie in Zeile 2 der Abb. 23 dargestellt, wird der Kunde mit der Funktion findById mit der ID
gesucht und anschließend mit remove aus der Datenbank gelöscht und auf die Indexseite der
Beispiel-Applikation weitergeleitet.
4.5 Überprüfung der Spezifikation
Nachdem sowohl die Benutzeroberfläche als auch die Logik der Beispiel-Applikation
implementiert wurden, muss nun noch überprüft werden, ob alle gestellten Anforderungen
der Spezifikation (siehe Kapitel 3.1) umgesetzt wurden.
Die mit Twitter Bootstrap entworfene GUI der Beispiel-Applikation bietet Zugriff auf alle, in
der Spezifikation gestellten, Anforderungen. Das Template für die Anmeldung eines Users
wird eingeblendet, falls keine gültige Authentifizierung vorhanden ist. Für das Abmelden eines
Users steht im Header ein dementsprechender Link zur Verfügung. Um einen neuen Kunden
speichern zu können, wird ein Formular in einer eigenen View dargestellt. Ebenso wird ein bestehender Kunde in einem Formular in der Detailansicht repräsentiert. Die Daten können
geändert und durch das Absenden des Formulars in die Datenbank gespeichert werden. Am
Ende derselben View kann mit Hilfe eines Delete-Buttons ein Kunde gelöscht werden.
Bei dem Entwurf der Benutzeroberfläche wurde besonders auf responsive Design geachtet.
Sämtliche Formulare, Buttons, Links und Textinhalte passen sich selbstständig an die
Bildschirmgröße des Endgerätes an.
Es wurde die NoSQL-Datenbank MongoDB verwendet, um User und Kunden zu verwalten. Der
Datenaustauch zwischen Anwendung und Datenbank erfolgt mit Hilfe des Datenformats JSON
(siehe Kapitel 3.2.3.1).
Für jeden Kunden kann ein individuelles Foto gespeichert werden. Durch den Fotoupload,
bietet die Anwendung die Möglichkeit, auf das lokale Dateisystem zuzugreifen.
5 Vor- und Nachteile von Node.js
Nachdem in den letzten Kapiteln die Beispiel-Applikation spezifiziert und implementiert
wurde, werden in diesem Kapitel anhand der Implementierung der Beispiel-Applikation die
Vor- und Nachteile von Node.js näher erläutert.
Die Beispiel-Applikation wurde mit folgenden Technologien entwickelt:
- JavaScript(server- und clientseitig)
- HTML(clientseitig)
- CSS(clientseitig)
Durch die serverseitige und clientseitige Verwendung von JavaScript spart sich der
Webentwickler das Erlernen einer zusätzlichen Programmiersprache. Außerdem wurde als
Datenbank MongoDB verwendet, somit entfällt auch eine komplexe Datenbanksprache wie
beispielsweise SQL. Bezogen auf die Firma AllBytes bedeutet das, dass die Ausbildung eines
einsetzbaren Entwicklers deutlich schneller vonstattengehen kann. Man benötigt nur noch
eine angemessene Zeit zur Einarbeitung in JavaScript um Node.js nutzen zu können. Wenn
man als bereits ausgebildeter, moderner Webentwickler den Einstieg in Node.js macht, fällt
dies relativ leicht, da bereits Kenntnisse von der clientseitigen JavaScript-Entwicklung
vorhanden sind.
An sich ist Node.js sehr schlank gehalten und konzentriert sich auf das Wesentliche. Um die
Anwendung zu erweitern, muss man passende Module installieren. Dies geschieht mit Hilfe
des npm (Node Package Manager), der ist sehr komfortabel und einfach zu bedienen, man
muss sich nicht um Abhängigkeiten von Modulen kümmern. Im Modul-Repository kann nach
gewünschten Modulen gesucht werden, hier sehe ich einen Nachteil, weil keine Hinweise
gegeben werden, wie gut ein Modul ist. Es bedarf Erfahrung, welche Module tatsächlich
benötigt werden und welche den Anforderungen standhalten.
Da Node-Prozesse nicht bei jeder Anfrage neu gestartet werden, wie das zum Beispiel in PHP
der Fall ist, muss sehr sauber programmiert werden. Vorsicht ist geboten, wenn Variablen
überschrieben oder Arrays gefüllt werden. Im Zusammenhang mit Arrays kann es schnell zu
Speicher-Problemen kommen, falls diese falsch befüllt werden.
Werden in Node.js Fehler nicht richtig abgefangen, kann es zu Problemen auf dem ganzen
Node-Server kommen. Wenn in PHP ein Fehler in einem Script auftaucht, betrifft dies nur eine
Anfrage und das Gesamtsystem läuft einfach weiter. In Node.js ist der gesamte Prozess
betroffen.
Node.js setzt auf Asynchronität, durch die parallele Abarbeitung der Anfragen ermöglicht
Node.js eine hohe Skalierbarkeit von Webanwendungen. Dadurch können gegenüber PHP und
Apache nicht nur mehr Anfragen eines Users verarbeitet werden, sondern auch mehr User
gleichzeitig auf eine Webseite zugreifen. Überlastete Server und unerreichbare Websites
sollen mit Node.js nicht mehr vorkommen.
Aufgrund der Neuartigkeit und Aktualität von Node.js, gab es zum Zeitpunkt der Niederschrift
dieser Arbeit wenig deutsche Literatur. Bei Problemen musste ich lange suchen und es gab
nur wenige Beispielanwendungen. Im Gegensatz zur PHP-Community ist die Node.js-
Community noch sehr klein, doch wächst diese rasant und es konnte innerhalb der letzen
Jahre ein umfassendes Ökosystem geschaffen werden. Um sich intensiv mit der Thematik
auseinandersetzen zu können, werden sehr gute Englischkenntnisse vorausgesetzt.
6 Wofür eignet sich Node.js
Aufbauend auf den Vor-und Nachteilen sowie meiner allgemeinen Einschätzung zu Node.js,
werden in diesem Kapitel die Einsatzmöglichkeiten von dem neuartigen serverseitigen
JavaScript Framework dargestellt. Es wird auch kurz darauf eingegangen, in welchen Fällen
der Einsatz ungeeignet oder zumindest weniger geeignet erscheint.
Das http-Modul (siehe Kapitel 3.2.2.1) macht es sehr einfach einen Webserver zu
implementieren. Die serverseitige Verwendung von JavaScript macht den Umgang mit dem
Datenformat JSON ebenfalls sehr komfortabel. Mit diesen zwei Komponenten können jegliche
Anwendungen, die JSON verarbeiten und zurückgeben, einfach und schnell implementiert
werden. Darunter fallen beispielsweise REST-basierte Webanwendungen oder sonstige APIs.
In der modernen Webentwicklung merkt man eine deutliche Tendenz zu Single-Page-
Anwendungen. Diese Anwendungen besitzen nur eine View und der Content wird meist
dynamisch nachgeladen. Da Single-Page-Anwendungen sehr JavaScript-lastig sind, kommt
Node.js, die Verwendung der Sprache JavaScript zugute. Außerdem übernimmt Node.js das
komplette Routing, was hierbei besonders praktisch ist. Single-Page-Anwendungen sind ein
geeignetes Szenario für Node.js.
Jetzt kommen wir zu zwei Szenarien, bei denen der Einsatz von Node.js sehr naheliegt. Zum
einen sind das alle Anwendungen die Streaming beinhalten, und zum anderen echtzeitfähige
Webanwendungen.
„Streams sind ein integrales Kernkonzept von Node.js, um Daten rasch und leichtgewichtig
auszuliefern. Außerdem lassen sich Streams in Node.js auf einfache Art orchestrieren, um
Daten auf verschiedenen Wegen durch eine Anwendung zu leiten.“. Beispielsweise lassen
sich Videos schon während des Hochladens in ein anderes Datenformat umwandeln.
In herkömmlichen Webanwendungen antwortet der Server auf einen Request des Clients,
doch in modernen Anwendungen wie beispielsweise Facebook will der User in Echtzeit
eingehende Nachrichten lesen können. In Node.js ist der Umgang mit sogenannten
Websockets sehr einfach, ein Websocket stellt eine permanente Verbindung dar, wo sowohl Client als auch Server jederzeit Daten schicken können. Es lassen sich in sehr kurzer Zeit echtzeitfähige Webanwendungen erstellen.
„Ein wesentliches Argument gegen den Einsatz von Node.js liegt vor, wenn kaum Interaktion
mit externen Ressourcen stattfindet. In einem solchen Fall kann Node.js seine Stärken im
Bereich Non-Blocking I/O nicht ausspielen und blockiert den einzigen Thread unnötig, so dass
eingehende Anfragen eventuell lange warten müssen. Dieses Verhalten gestaltet sich desto
schlimmer, je rechenintensiver eine Webanwendung ist. Typische CRUD-Anwendungen
(Datenbankoperationen -> Create, Read, Update, Delete), die Daten ohne größere
Verarbeitung lediglich zwischen Webbrowser und Datenbank übertragen, sind ebenfalls kein
herausragender Anwendungsfall für Node.js.“Meiner Erfahrung nach, ist bei CRUD-
Anwendungen Node.js nicht besser oder schlechter als PHP oder vergleichbare Technologien.
Node.js kann dort nur seine Stärken nicht ausspielen.
Zusammenfassend stellt Node.js für folgende Anwendungsfälle und Anforderungen eine
geeignete Plattform zur Entwicklung von Webanwendungen dar:
- Streaming
- Echtzeitfähige Webanwendungen
- CRUD-Anwendungen
- Single-Page-Anwendungen
- REST-basierte Webanwendungen oder sonstige APIs
- Wenn hohe Skalierbarkeit der Webanwendung erwartet wird
- Wenn eine hohe Performance der Webanwendung erwartet wird
7 Schlussbetrachtung
Ziel der Arbeit war, den grundsätzlichen Aufbau von Node.js näher zu erläutern, außerdem
sollte anhand der Implementierung einer Node.js-Beispiel-Applikation festgestellt werden, ob
sich die Bestandteile einer modernen Webanwendung umsetzen lassen. Zusätzlich sollten die
wesentlichsten Unterschiede zu einer herkömmlichen Skriptsprache, im speziellen PHP,
dargestellt werden, sowie die Vor- und Nachteile beschrieben werden.
7.1 Fazit
Insgesamt kann festgestellt werden, dass moderne Webanwendungen, die bis weil in PHP
programmiert wurden, ebenso in Node.js umgesetzt werden könnten. In den meisten
Anwendungsszenarien macht es durchaus Sinn, Node.js zu verwenden. Es hängt von den
Anforderungen und Vorgaben ab, die an ein System gestellt werden. Sicher ist, dass man bei
der Entwicklung von modernen Webanwendungen als Programmierer nicht mehr um
JavaScript herumkommt. Wie man in der Beispiel-Applikation sehen kann, kann man sich durch den serverseitigen Einsatz von JavaScript das Erlernen einer weiteren Programmiersprache wie PHP ersparen. Durch den Einsatz von Node.js verkürzt sich die
Ausbildungsdauer eines Auszubildenden bis hin zum einsetzbaren Webentwickler erheblich.
Der grundsätzliche Aufbau von Node.js ist sehr übersichtlich gestaltet. Als Entwickler findet
man sich rasch zurecht, nach kurzer Einarbeitungszeit hat man sich schnell an den modularen
Aufbau sowie an die Vielfalt der bereitgestellten Module gewöhnt. Es können in kurzer Zeit
komplexe Webanwendungen erstellt werden.
7.2 Ausblick
Wie man aus folgender Grafik (siehe Abb. 24) von Google Trends entnehmen kann, steigt das
Interesse an Node.js stetig an. Node.js ist der Zeit lange nicht so weit verbreitet wie PHP, doch
ist dies meiner Meinung nach, mit der Veränderung des Web hin zu modernen und
dynamischen Anwendungen, erst der Anfang von Node.js.
Abb. 24 Google Trends – Interesse an Node.js (https://nodecode.de/, Zugriff: 27.03.2014)
Das junge Framework Node.js hat seit 2009 einen Stand erreicht, der als Grundlage für
umfangreiche Entwicklungen dienen kann. Die Community um das serverseitige JavaScript-
Framework Node.js wächst stetig und gewinnt zunehmend an Professionalität. Nicht nur
durch die Integration von Node.js im Dezember 2013 in Microsofts Entwicklungsumgebung
Visual Studio ist zu erwarten, dass das Framework eine große Anzahl an Entwicklern gewinnen
wird.
Durch die Umsetzung der Beispiel-Applikation und den Erkenntnissen, die ich aus dieser Arbeit
ziehen konnte, bin ich mir sicher, dass mich Node.js in meiner Zukunft weiter begleiten wird.
Abkürzungsverzeichnis
- AJAX
- Asynchronous JavaScript and XML
- API
- Application Programming Interface
- CRUD
- Create- Read- Update- Delete
- CSS
- Cascading Style Sheets
- DB
- Datenbank
- GUI
- Graphical User Interface
- HTML
- HyperText Markup Language
- http
- HyperText Transfer Protocol
- https
- HyperText Transfer Protocol Secure
- IDE
- Integrated Development Environment
- JS
- JavaScript
- JSON
- JavaScript Object Notation
- npm
- Node Package Manager
- UML
- Undified Modeling Language
- URL
- Uniform Resource Locator
- XML
- Extensible Markup Language
Literaturverzeichnis
Gedruckte Quellen:
Firtman, Maximiliano: Programming the Mobile Web, 1.Auflage O’Reilly & Associates Verlag
2010
Ornbo, George: Sams Teach Yourself Node.js in 24 Hours – 24 Proven One-Hour Lessons,
1.Auflage Sams-Verlag 2012
Roden, Golo: Node.js & Co. – Skalierbare, hochperformante und echtzeitfähige
Webanwendungen professionell in JavaScript entwickeln, 1. Auflage dpunkt.verlag 2012
Steyer, Ralph: JavaScript – Das Programmier-Handbuch, 1. Auflage Markt+Technik Verlag
2001
Website:
cade_metz: Google’s Chrome Browser Sprouts Programming Kit of the Future
http://www.wired.com/wiredenterprise/2012/01/node-dot-js/ (Zugriff: 31.01.2014)
Graf, Ralf: Serverseitiges JavaScript mit Node.js
http://webkrauts.de/artikel/2011/serverseitiges-javascript-mit-nodejs (Zugriff: 26.03.2014)
Hänsch, Carl-Philip: Node.js vs. PHP+Apache http://www.mywebcheck.de/node-js-vs-phpapache/ (Zugriff: 25.02.2014)
Huawei Technologies Deutschland GmbH: Initiative D21 und Huawai Technologies stellen
Studie zur mobilen Internetznutzung vor
https://initiatived21.de/themen/bildung-und-digitalkompetenzen (Zugriff:01.04.2014)
Json – http://www.json.org (Zugriff: 17.03.2014)
Karadeniz, Besim: Der Internet-Boom und die Dot-Comshttp://www.netplanet.org/geschichte/neunziger.shtml (Zugriff: 31.01.2014)
MongoDB – Agile and Scalable http://www.mongodb.org/ (Zugriff: 26.02.2014)
Node.js: Node.js – Manual & Documentation http://nodejs.org/docs/latest/api/index.html (Zugriff: 28.02.2014)
NodeCode: PHP vs. Node.js – Gemeinsamkeiten & Unterschiede http://nodecode.de/php-vs-nodejs (Zugriff: 26.02.2014)
NodeCode: PHP vs. Node.js – Gemeinsamkeiten & Unterschiede http://nodecode.de/php-vs-nodejs (Zugriff: 28.02.2014)
Pahrmann, Corina: Node.js – Blitzschnelles und stabiles JavaScript
http://community.oreilly.de/blog/2013/01/23/node-js-blitzschnelles-und-stabiles-javascript/ (Zugriff: 26.03.14)
Petereit, Dieter: Bootstrap: CSS- und HTML5-basiertes WebApp-Toolkit von Twitter
http://t3n.de/news/bootstrap-css-html5-basiertes-webapp-toolkit-twitter-327063/ (Zugriff:
03.03.2014)
Roden, Golo: 2x Nein, 4x Ja: Szenarien für Node.js
http://www.heise.de/developer/artikel/2x-Nein-4x-Ja-Szenarien-fuer-Node-js-2111050.html (Zugriff: 27.03.14)
Roden, Golo: Node-Force-Domain https://github.com/goloroden/node-force-domain (Zugriff: 05.03.2014)
Roden, Golo: Rest-Webservices mit Node.js – Teil1: Connect als Fundament
http://www.heise.de/developer/artikel/REST-Webservices-mit-Node-js-Teil-1-Connect-als-Fundament-1802258.html / (Zugriff: 24.02.2014)
(10)Springer, Sebastian: Node.js – Das Framework im Überblick
http://t3n.de/magazin/serverseitige-javascript-entwicklung-nodejs-einsatz-231152/ (Zugriff: 31.01.2014)
Twitter Bootstrap – http://getbootstrap.com/2.3.2/ (Zugriff: 03.03.2014)
Wikipedia – JavaScript http://de.wikipedia.org/wiki/JavaScript (Zugriff: 01.04.2014)