Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Marco Rico Gomez | Weigle Wilczek GmbH

Leichtgewichtige Webanwendungen mit
dem MEAN Stack
Agenda
●

Überblick MEAN-Stack
–

●

Warum?
–

●

Architektur einer modernen Webanwendung
Was spricht für diesen Technolog...
Was ist der MEAN Stack?
●

●

Technologiestack für die Entwicklung von
Webanwendung
Valeri Karpov, April 2013
M

E

A

N
Architektur
Warum?
Eine Programmiersprache
MongoDB
db.foo.find({ foo: 'bar' });

Node.JS/ Express.JS
app.get('/api/foo/:bar', function (req, ...
Ein Datenformat (JSON)
{
"title": "Foo Bar",
"type": 12
}

{
"title": "Foo Bar",
"type": 12
}

{
"title": "Foo Bar",
"type...
Keine Schemamigrationen

ALTER TABLE foo ADD COLUMN bar
VARCHAR(200) NOT NULL;

Schema wird in der Anwendung definiert.
Geringer Resourcenverbrauch
●

kein (wenig) UI-Rendering auf dem Server

●

ereignisgesteuerte Architektur / Non-blocking ...
Wie?
app.js
// declare module dependencies ...
var express = require('express');
// more ...
var app = express();
// configure ...
Express API (HTTP Verben)
●

app.get(path, [callback...], callback)

●

app.post(path, [callback...],callback)

●

app.put...
Routen sind einfache Funktionen

app.get('/api/foo', function (req, res) {
res.send({ foo: 'bar' });
});
Routen filtern (Wildcards)

app.all("/app/*", function (req, res, next) {
if (isUserLoggedIn) next();
else res.redirect('/...
Routen (Variablen)

app.put("/api/task/:id", function(req, res, next) {
res.send("Your request id: " + req.params.id);
});
MongoDB
{

}

"name": "Create something beautiful",
"dueBy": Date(2013, 10, 1),
"priority": 2,
"done": false,
"subTasks": ...
Join-less
{
"name": "Create something beautiful",
"dueBy": Date(2013, 10, 1),
"priority": 2,
"done": false,
"subTasks": [
...
Adhoc-Abfragen
db.tasks.find({
done: false,
dueBy: {
$gte: new Date(2013, 10, 1),
$lt: new Date(2013, 11, 1)
},
priotity: ...
Mongoose
var mongoose = require('mongoose');
var Task = mongoose.model('Task', {
name: { type: String, required: true },
d...
Validierung

Task.schema.path('priority')
.validate(function (value) {
return (value >= 0 && value <= 2)
}, 'Invalid prior...
Validierung
{
"message": "Validation failed",
"name": "ValidationError",
"errors": {
"priority": {
"message": "Validator f...
RESTful APIs erstellen

app.post('/api/tasks', function(req, res) {
var newTask = new model.Task(req.body);
newTask.save(f...
AngularJS
●

clienseitiges JavaScript Framework für WebApps.
–

Templates

–

Model-View-Controller

–

Dependency Injecti...
Bootstrapping Angular
<!doctype html>
<html lang="en" ng-app="demo">
<head>
...
</head>
<body ng-init="hello='Hello World'...
Bootstrapping Angular (2)
<!doctype html>
<html lang="en" ng-app="demo">
<head>
...
</head>
<body ng-init="hello='Hello Wo...
Templates & Databinding
Direktiven
●
●
●
●
●
●
●
●

ng-include
ng-click
ng-hide/ ng-show
ng-class
ng-cloak
ng-repeat
ng-model
…
Scopes & Controllers

angular.controller();
Client-side Services
●

Services sind Singletons
–
–

●

kapseln Funktionalität
können mittels Angular DI injiziert werden...
Dependency Injection

function DemoCtrl ($scope, $resource) {
...
}
RESTful APIs konsumieren
●

ngResource Modul
–

Support für Zugriff auf RESTful APIs

–

$resource-Service
●
●
●
●

query(...
HTML erweitern (Direktiven)
●

eigene Komponentenen definieren
–

●

DOM-Transformation

vorhandene Elemente um neues Verh...
Direktiven (2)
●

eigene Komponenten erstellen (don't repeat your
self)
Direktiven (3)
●

angular-ui Projekt
–

ui-bootstrap (Accordion/ Tabs/ Alerts/ Carousel)

–

ng-grid

–

ui-router

–

sel...
Tooling

http://yeoman.io
Q&A

rico@weiglewilczek.com

@mricog
Leichtgewichtige Webwenwendungen mit dem MEAN-Stack
Leichtgewichtige Webwenwendungen mit dem MEAN-Stack
Leichtgewichtige Webwenwendungen mit dem MEAN-Stack
Leichtgewichtige Webwenwendungen mit dem MEAN-Stack
Upcoming SlideShare
Loading in …5
×

Leichtgewichtige Webwenwendungen mit dem MEAN-Stack

1,757 views

Published on

Gerade bei Web-Anwendungen ist es wichtig Anforderungen schnell umsetzen zu können. Dazu sollte der Stack den Entwickler unterstützten und nicht durch unnötige Abstraktionen weitere Hürden aufbauen. Zurück zur Einfachheit ist hier die Devise!
MEAN steht für MongoDB, ExpressJS, AngularJS und Node.js. Server und Frontend werden dank Node.JS in einer gmeinsamen Programmiersprache entwickelt: JavaScript. JSON-Datenstrukturen können ohne größere Umwege mittels ExpressJS aus der Datenbank an AngularJS übergeben werden; ein aufwändiges OR-Mapping entfällt. AngularJS erlaubt es mittels Direktiven das HTML-Subset um anwendungsspezifisches Verhalten zu erweitern.
Dieser Vortrag gibt einen Einblick in die Entwicklung von Web-Anwendungen mit dem MEAN-Stack und zeigt das Zusammenspiel der einzelnen Komponenten.

Published in: Technology, Business
  • Be the first to comment

Leichtgewichtige Webwenwendungen mit dem MEAN-Stack

  1. 1. Marco Rico Gomez | Weigle Wilczek GmbH Leichtgewichtige Webanwendungen mit dem MEAN Stack
  2. 2. Agenda ● Überblick MEAN-Stack – ● Warum? – ● Architektur einer modernen Webanwendung Was spricht für diesen Technologiestack Wie? – – Datenmodell und -speicherung – ● Der Server Frontend Tooling
  3. 3. Was ist der MEAN Stack? ● ● Technologiestack für die Entwicklung von Webanwendung Valeri Karpov, April 2013
  4. 4. M E A N
  5. 5. Architektur
  6. 6. Warum?
  7. 7. Eine Programmiersprache MongoDB db.foo.find({ foo: 'bar' }); Node.JS/ Express.JS app.get('/api/foo/:bar', function (req, res, next) { res.send({ foo: 'bar' }); }); AngularJS: angular.controller('FooCtrl', function ($scope, $resource) { var Foo = $resource('/api/foo/:bar', { bar: '@id'}); $scope.bar = Foo.get({bar: 'bar'}); });
  8. 8. Ein Datenformat (JSON) { "title": "Foo Bar", "type": 12 } { "title": "Foo Bar", "type": 12 } { "title": "Foo Bar", "type": 12 }
  9. 9. Keine Schemamigrationen ALTER TABLE foo ADD COLUMN bar VARCHAR(200) NOT NULL; Schema wird in der Anwendung definiert.
  10. 10. Geringer Resourcenverbrauch ● kein (wenig) UI-Rendering auf dem Server ● ereignisgesteuerte Architektur / Non-blocking I/O
  11. 11. Wie?
  12. 12. app.js // declare module dependencies ... var express = require('express'); // more ... var app = express(); // configure express ... app.use(express.logger('dev')); app.use(express.bodyParser()); app.use(app.router); // more ... // define routes ... app.get('/', routes.index); app.get('/users', user.list); // ... and go!! http.createServer(app).listen(app.get('port'), function() { console.log('Express server listening on port ' + app.get('port')); });
  13. 13. Express API (HTTP Verben) ● app.get(path, [callback...], callback) ● app.post(path, [callback...],callback) ● app.put(path, [callback...], callback) ● app.delete(path, [callback...],callback) ● ... callback = function (req, res, next) { … }
  14. 14. Routen sind einfache Funktionen app.get('/api/foo', function (req, res) { res.send({ foo: 'bar' }); });
  15. 15. Routen filtern (Wildcards) app.all("/app/*", function (req, res, next) { if (isUserLoggedIn) next(); else res.redirect('/login'); });
  16. 16. Routen (Variablen) app.put("/api/task/:id", function(req, res, next) { res.send("Your request id: " + req.params.id); });
  17. 17. MongoDB { } "name": "Create something beautiful", "dueBy": Date(2013, 10, 1), "priority": 2, "done": false, "subTasks": [ { "name": "blabla", "done": true, }, { "name": "blabla", "done": false } ] dokumentenorientiert schemafrei
  18. 18. Join-less { "name": "Create something beautiful", "dueBy": Date(2013, 10, 1), "priority": 2, "done": false, "subTasks": [ { "name": "blabla", "done": true, }, { "name": "blabla", "done": false } ] } verschachtelte Datenstrukturen 16 MB Limit beachten !
  19. 19. Adhoc-Abfragen db.tasks.find({ done: false, dueBy: { $gte: new Date(2013, 10, 1), $lt: new Date(2013, 11, 1) }, priotity: { $in: [0, 2] }, subTasks: { $exists: true } }).sort({dueBy: -1}).limit(10);
  20. 20. Mongoose var mongoose = require('mongoose'); var Task = mongoose.model('Task', { name: { type: String, required: true }, done: { type: Boolean, default: false }, dueBy: Date, priority: Number });
  21. 21. Validierung Task.schema.path('priority') .validate(function (value) { return (value >= 0 && value <= 2) }, 'Invalid priority');
  22. 22. Validierung { "message": "Validation failed", "name": "ValidationError", "errors": { "priority": { "message": "Validator failed for ...", "name": "ValidatorError", "path": "priority", "type": "Invalid priority", "value": 4 } } Detaillierte Fehlerinformationen Einfach, diese generisch im Client anzuzeigen
  23. 23. RESTful APIs erstellen app.post('/api/tasks', function(req, res) { var newTask = new model.Task(req.body); newTask.save(function (err) { if (err) return res.send(422, err); res.send(201); }); };
  24. 24. AngularJS ● clienseitiges JavaScript Framework für WebApps. – Templates – Model-View-Controller – Dependency Injection – Data-Binding – Direktiven – Views und Routen
  25. 25. Bootstrapping Angular <!doctype html> <html lang="en" ng-app="demo"> <head> ... </head> <body ng-init="hello='Hello World'"> {{ hello }} <script src="assets/angular.js"></script> <script> // separate file(s) (!) angular.module("demo", []); </script> </body> </html>
  26. 26. Bootstrapping Angular (2) <!doctype html> <html lang="en" ng-app="demo"> <head> ... </head> <body ng-init="hello='Hello World'"> Hello World <script src="assets/angular.js"></script> <script> // separate file(s) (!) angular.module("demo", []); </script> </body> </html>
  27. 27. Templates & Databinding
  28. 28. Direktiven ● ● ● ● ● ● ● ● ng-include ng-click ng-hide/ ng-show ng-class ng-cloak ng-repeat ng-model …
  29. 29. Scopes & Controllers angular.controller();
  30. 30. Client-side Services ● Services sind Singletons – – ● kapseln Funktionalität können mittels Angular DI injiziert werden. Built-in – $http, $window, $document, $filter, ... angular.factory(„myService“, function() {});
  31. 31. Dependency Injection function DemoCtrl ($scope, $resource) { ... }
  32. 32. RESTful APIs konsumieren ● ngResource Modul – Support für Zugriff auf RESTful APIs – $resource-Service ● ● ● ● query() get() save() delete()
  33. 33. HTML erweitern (Direktiven) ● eigene Komponentenen definieren – ● DOM-Transformation vorhandene Elemente um neues Verhalten erweitern angular.directive();
  34. 34. Direktiven (2) ● eigene Komponenten erstellen (don't repeat your self)
  35. 35. Direktiven (3) ● angular-ui Projekt – ui-bootstrap (Accordion/ Tabs/ Alerts/ Carousel) – ng-grid – ui-router – select2 – codeMirror – ... http://angular-ui.github.io/
  36. 36. Tooling http://yeoman.io
  37. 37. Q&A rico@weiglewilczek.com @mricog

×