Webapplikationen mit Node.js

68
für Webapplikationen

description

Wie erstelle ich Webapplikationen mit Node.js. Vorgestellt werden verschiedene Frameworks wie Express.js oder Koa. Außerdem wird auf Skalierung eingegangen.

Transcript of Webapplikationen mit Node.js

Page 1: Webapplikationen mit Node.js

für Webapplikationen

Page 2: Webapplikationen mit Node.js

Alexandra H. / pixelio.de

Page 3: Webapplikationen mit Node.js

WER BIN ICH?

• Sebastian Springer

• https://github.com/sspringer82

• @basti_springer

• Consultant, Trainer, Autor

Page 4: Webapplikationen mit Node.js
Page 5: Webapplikationen mit Node.js

Rudolpho Duba / pixelio.de

Page 6: Webapplikationen mit Node.js

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');!!console.log('Server running at localhost');

Heute machen wir kein plain Node.js

Page 7: Webapplikationen mit Node.js

Wie baue ich mit Node.js eine stabile und performante Webapplikation?

Für die ich mich später nicht schämen muss…

Page 8: Webapplikationen mit Node.js

Struktur

Monika Weidenhaupt / pixelio.de

Page 9: Webapplikationen mit Node.js

Struktur bedeutet Organisation des Quellcodes in Komponenten, Dateien und Verzeichnisse.

Ziel ist eine Verbesserung der Wartbarkeit und Erweiterbarkeit.

…und ja, das geht mit Node.js

Page 10: Webapplikationen mit Node.js

Modulsystem

Das Node.js-Modulsystem zur Aufteilung in Dateien nutzen.

Einbinden von Dateien kostet nichts, Node.js verfügt über einen Modulcache.

Page 11: Webapplikationen mit Node.js

$ node cache2.js In Module Module function Module function

var foo = require('./myFile'); var bar = require('./myFile'); !foo.myFunc(); bar.myFunc();

console.log('In Module'); !module.exports = { myFunc: function() {console.log('Module function');} };

Page 12: Webapplikationen mit Node.js

Frameworks?Beat Kohler / pixelio.de

Page 13: Webapplikationen mit Node.js

Frameworks liefern Strukturkomponenten, Hilfsfunktionen und eine Reihe von Best Practices.

!Frameworks lösen Probleme, von denen du noch nicht einmal

wusstest, dass du sie haben wirst.

Page 14: Webapplikationen mit Node.js

! Templating" Modular # Routing $ Extensible

Jade HandlebarsMiddleware MiddlewareHTTP-Methods

Sehr weit verbreitetes Web Application Framework auf Basis von Node.js-http und Connect.

Page 15: Webapplikationen mit Node.js

var express = require('express');!var app = express();!!app.get('/', function(req, res){! res.send('hello world');!});!!app.listen(3000);

Page 16: Webapplikationen mit Node.js

! Templating" Modular # Routing $ Extensible

Jade HandlebarsMiddleware MiddlewareHTTP-Methods

Neues, noch experimentelles Framework, das auf ECMAScript 6-Features setzt (min. node-v0.11).

Bessere Unterstützung von Promises und potenzieller Nachfolger von express.

Page 17: Webapplikationen mit Node.js

var koa = require('koa');!var app = koa();!!// logger!app.use(function *(next){! var start = new Date;! yield next;! var ms = new Date - start;! console.log('%s %s - %s', this.method, ! this.url, ms);!});!!// response!app.use(function *(){! this.body = 'Hello World';!});!!app.listen(3000);

Page 18: Webapplikationen mit Node.js

! Templating" Modular # Routing $ Extensible

PlatesMiddleware Middleware PluginsDirector

Ein wesentlich kleineres Framework als express. Unterstützt die wichtigsten Funktionen, die für den Aufbau einer Web

Applikation benötigt werden.

Page 19: Webapplikationen mit Node.js

var flatiron = require('flatiron'),! app = flatiron.app;!!app.use(flatiron.plugins.http);!!app.router.get('/', function () {! this.res.writeHead(200, { ! 'Content-Type': 'text/plain' ! });! this.res.end('Hello world!\n');!});!!app.start(8080);

Page 20: Webapplikationen mit Node.js

! Templating" Modular # Routing $ Extensible

own engineModules OverwritesHTTP-Methods

Im Vergleich zu express ein vergleichsweise kleines Framework. Umfangreiche Abdeckung der Problemstellungen.

Page 21: Webapplikationen mit Node.js

var framework = require('total.js');!var http = require('http');! !var debug = true;! !framework.run(http, debug, 8005);

exports.install = function(framework) {! framework.route('/', view_homepage);! framework.route('/{link}/', view_detail);!};! !function view_homepage() {! var self = this;! self.view('homepage');!}

Page 22: Webapplikationen mit Node.js
Page 23: Webapplikationen mit Node.js

Wir bauen eine MVC-Applikation.

Page 24: Webapplikationen mit Node.js

Wir bauen eine MVC-Applikation

Bernd Kasper / pixelio.de

Page 25: Webapplikationen mit Node.js

Verzeichnisstruktur.!!"" controllers!#   $"" index.js!!"" index.js!!"" models!#   $"" user.js!!"" public!!"" router.js!$"" views! $"" login.js

Page 26: Webapplikationen mit Node.js

index.jsvar express = require('express');!var bodyParser = require('body-parser');!var routes = require('./router');!!var app = express();!!app.use(bodyParser.json());!!app.use('/', express.static(__dirname + '/public'));!!routes(app);!!app.listen(8080);

Page 27: Webapplikationen mit Node.js

router.jsvar express = require('express');!!var todoController = require('./controllers/todo');!!module.exports = function(app) {! var todoRouter = express.Router();!! todoRouter.get('/', todoController.getAllAction);! todoRouter.get('/:id', todoController.getOneAction);! todoRouter.post('/', todoController.createAction);! todoRouter.put('/:id', todoController.updateAction);! todoRouter.delete('/:id', todoController.deleteAction);!! app.use('/todo', todoRouter);!};

Page 28: Webapplikationen mit Node.js

Controller

Funktionen, die hinter den einzelnen Routen stehen. Erhalten das Request- und Response-Objekt.

Page 29: Webapplikationen mit Node.js

Models

Hier liegt die eigentliche Business-Logik der Applikation. Die eingehenden Informationen werden validiert und

verarbeitet und gegebenenfalls in die Datenbank gespeichert.

Page 30: Webapplikationen mit Node.js

Datenbanken?

Tim Reckmann / pixelio.de

Page 31: Webapplikationen mit Node.js

Datenbanken

Page 32: Webapplikationen mit Node.js

1. Treiber installieren !npm install sqlite3

2. Verbindung aufbauen !var db = new sqlite3.Database(‘./db/myDb.db');

3. Abfragen !db.get(sql, id, function(err, row) {! … !});

Page 33: Webapplikationen mit Node.js

Promises

mit QJMG / pixelio.de

Das Versprechen auf die Erfüllung einer asynchronen Funktion.

Page 34: Webapplikationen mit Node.js

db.query(sql, function(err, data) {! if(err) {! throw err;! } else {! console.log(data);! }!});

Page 35: Webapplikationen mit Node.js

var q = require(‘q’);!!function queryWrapper(sql) {! var deferred = q.defer();! db.query(sql, function(err, data) {! if(err) {! deferred.reject(err);! } else {! deferred.resolve(data);! }! });! return deferred.promise;!}

Page 36: Webapplikationen mit Node.js

var sql = ‘SELECT * FROM users’;!!var promise = queryWrapper(sql)!!promise.then(function(data) {! // success ! …!}, function(err) {! // failure! …!});

Page 37: Webapplikationen mit Node.js

Warum Promises?

Escape the Callback Hell!

Bessere Flusssteuerung für asynchrone Calls wie z.B. Merge.

Quasi synchrone Programmierung trotz Asynchronität

Page 38: Webapplikationen mit Node.js

Promises mit koa

// curl -X GET http://localhost:8080/user/1!app.get('/user/:id', function *(next) {! var user = yield movieModel.get(this.params.id);! this.body = JSON.stringify(user);!});

Page 39: Webapplikationen mit Node.js

ORM

&○␣␣

Page 40: Webapplikationen mit Node.js

var express = require('express');!var orm = require('orm');!var app = express();!!app.use(orm.express("mysql://username:password@host/database", {! define: function (db, models, next) {! models.person = db.define("person", { ... });! next();! }!}));!app.listen(80);!!app.get("/", function (req, res) {! req.models.person.find(...);!});

npm install orm

Page 41: Webapplikationen mit Node.js

Template Engines

Page 42: Webapplikationen mit Node.js

Paketverwaltung

Page 43: Webapplikationen mit Node.js

Der Node Package Manager ist seit der Version 0.6.3 Teil von Node.js.

Installation, Update und Removal von Paketen. Das zentrale Repo liegt unter npmjs.org.

Aktuell gibt es > 83k Pakete. Jeder kann Pakete veröffentlichen.

!Jedes Paket löst seine eigenen Abhängigkeiten auf.

Page 44: Webapplikationen mit Node.js

Konfigurationsdatei für ein Projekt. Wird mit npm init erstellt.

Enthält viele Meta-Informationen und die Abhängigkeiten.

package.json

Page 45: Webapplikationen mit Node.js

• node_modules: Verzeichnis, in das die Abhängigkeiten installiert werden (sollte im VCS ignoriert werden).

!• npm install: Installiert sämtliche Abhängigkeiten aus der

package.json automatisch. !• npm install --save: Trägt die Abhängigkeiten in die

package.json ein.

Page 46: Webapplikationen mit Node.js

Distribution

Gabi Schoenemann / pixelio.de

Page 47: Webapplikationen mit Node.js

• Installation über npmjs.org

• Installation eines Pakets aus einem Verzeichnis

• Installation eines Pakets aus einer .tgz-Datei

Voraussetzung: package.json muss vorhanden sein

Page 48: Webapplikationen mit Node.js

Skalierung

Page 49: Webapplikationen mit Node.js

Node.js ist im Kern klein und leichtgewichtig. Node.js ist Single-Threaded.

Node.js schlägt sich als Einzelkämpfer recht gut.

ABER: das alles hat auch seine Grenzen.

Page 50: Webapplikationen mit Node.js

Multi-Threaded

lichtkunst.73 / pixelio.de

Page 51: Webapplikationen mit Node.js

Mit Boardmitteln

)child_process cluster

Page 52: Webapplikationen mit Node.js

child_process

Manuelles Forken von Kindprozessen. Prozesse können über Nachrichten kommunizieren.

ACHTUNG: Kinder kosten … Ressourcen

Page 53: Webapplikationen mit Node.js

var cp = require('child_process');!!var sub = cp.fork(__dirname + '/sub.js');!!sub.on('message', function(m) {! console.log('PARENT got message:', m);!});!!sub.send({ hello: 'world' });

process.on('message', function(m) {! console.log('CHILD got message:', m);!});!!process.send({ foo: 'bar' });

Parent

Child

Page 54: Webapplikationen mit Node.js

cluster

Skalierung für socket-basierte Module wie z.B. http. Betriebssystem übernimmt das Loadbalancing.

Die Prozesse teilen sich einen Port.

Page 55: Webapplikationen mit Node.js

var cluster = require('cluster');!var http = require('http');!var numCPUs = require('os').cpus().length;!!if (cluster.isMaster) {! for (var i = 0; i < numCPUs; i++) {! cluster.fork();! }!! cluster.on('exit', function(worker, code, signal) {! console.log('worker ' + worker.process.pid + ' died');! });!} else {! http.createServer(function(req, res) {! res.writeHead(200);! res.end("hello world\n");! }).listen(8000);!}

Page 56: Webapplikationen mit Node.js

In die Breite

Page 57: Webapplikationen mit Node.js

Loadbalancer

Node Server 1 Node Server 2

Datenbank

Page 58: Webapplikationen mit Node.js

*cloud

Hasan Anac / pixelio.de

Page 59: Webapplikationen mit Node.js

Performance

Thomas Siepmann / pixelio.de

Page 60: Webapplikationen mit Node.js

Performance• Kein synchroner Code

• Keine statischen Assets - z.B. Nginx einsetzen

• Den Client rendern lassen - JSON-Kommunikation

• gzip nutzen

• Binärmodule sind schneller - z.B. mySQL

Page 61: Webapplikationen mit Node.js

Qualität

Karl-Heinz Laube / pixelio.de

Page 62: Webapplikationen mit Node.js

jslint/jshint

npm install -g jslint !

Werkzeuge zur statischen Codeanalyse. Finden Syntaxfehler und Antipatterns.

$ jslint index.js !index.js #1 Unexpected dangling '_' in '__dirname'. app.use('/', express.static(__dirname + '/public')); // Line 9, Pos 29

Page 63: Webapplikationen mit Node.js

Copy-Paste-Detection

npm install -g jscpd !

Findet duplizierten Quellcode im Projekt.

$ jscpd -f app.js !info: Found 7 exact clones with 70 duplicated lines in 1 files - app.js:6626 -6635 app.js:6646 -6655

Page 64: Webapplikationen mit Node.js

Plato

npm install -g plato !

Visualisierung der Komplexität einer Applikation. Metriken: Maintainability, Lines of Code, Estimated Errors in

Implementation, Lint Errors

Page 65: Webapplikationen mit Node.js
Page 66: Webapplikationen mit Node.js

Testing

assert

Mocha

nodeunit

jasmine-node

uygar sanli / pixelio.de

Page 67: Webapplikationen mit Node.js

Janina Briesemeister / pixelio.de

Page 68: Webapplikationen mit Node.js

KONTAKT

Sebastian Springer [email protected] !Mayflower GmbH Mannhardtstr. 6 80538 München Deutschland !@basti_springer !https://github.com/sspringer82