webapplikationen mit node.js

Post on 13-Jan-2015

272 Views

Category:

Internet

1 Downloads

Preview:

Click to see full reader

DESCRIPTION

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

TRANSCRIPT

für Webapplikationen

Alexandra H. / pixelio.de

WER BIN ICH?

• Sebastian Springer

• https://github.com/sspringer82

• @basti_springer

• Consultant, Trainer, Autor

Rudolpho Duba / pixelio.de

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

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

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

Struktur

Monika Weidenhaupt / pixelio.de

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

Modulsystem

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

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

$ 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');} };

Frameworks?Beat Kohler / pixelio.de

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.

! Templating" Modular # Routing $ Extensible

Jade HandlebarsMiddleware MiddlewareHTTP-Methods

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

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

! 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.

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);

! 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.

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);

! Templating" Modular # Routing $ Extensible

own engineModules OverwritesHTTP-Methods

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

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');!}

Wir bauen eine MVC-Applikation.

Wir bauen eine MVC-Applikation

Bernd Kasper / pixelio.de

Verzeichnisstruktur.!!"" controllers!#   $"" index.js!!"" index.js!!"" models!#   $"" user.js!!"" public!!"" router.js!$"" views! $"" login.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);

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);!};

Controller

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

Models

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

verarbeitet und gegebenenfalls in die Datenbank gespeichert.

Datenbanken?

Tim Reckmann / pixelio.de

Datenbanken

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) {! … !});

Promises

mit QJMG / pixelio.de

Das Versprechen auf die Erfüllung einer asynchronen Funktion.

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

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;!}

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

Warum Promises?

Escape the Callback Hell!

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

Quasi synchrone Programmierung trotz Asynchronität

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);!});

ORM

&○␣␣

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

Template Engines

Paketverwaltung

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.

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

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

package.json

• 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.

Distribution

Gabi Schoenemann / pixelio.de

• Installation über npmjs.org

• Installation eines Pakets aus einem Verzeichnis

• Installation eines Pakets aus einer .tgz-Datei

Voraussetzung: package.json muss vorhanden sein

Skalierung

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.

Multi-Threaded

lichtkunst.73 / pixelio.de

Mit Boardmitteln

)child_process cluster

child_process

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

ACHTUNG: Kinder kosten … Ressourcen

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

cluster

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

Die Prozesse teilen sich einen Port.

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);!}

In die Breite

Loadbalancer

Node Server 1 Node Server 2

Datenbank

*cloud

Hasan Anac / pixelio.de

Performance

Thomas Siepmann / pixelio.de

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

Qualität

Karl-Heinz Laube / pixelio.de

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

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

Plato

npm install -g plato !

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

Implementation, Lint Errors

Testing

assert

Mocha

nodeunit

jasmine-node

uygar sanli / pixelio.de

Janina Briesemeister / pixelio.de

KONTAKT

Sebastian Springer sebastian.springer@mayflower.de !Mayflower GmbH Mannhardtstr. 6 80538 München Deutschland !@basti_springer !https://github.com/sspringer82

top related