SlideShare a Scribd company logo
Scalable Angular 2 Application Architecture
Scalable
Application rchitecture
github.com/mgechev
twitter.com/mgechev
blog.mgechev.com
Scalable Angular 2 Application Architecture
Scalable Angular 2 Application Architecture
STANG2
50% off
Agenda
– Martin Fowler
“…decisions that are hard to
change…”
Architecture
Story Time
Dynamic
Requirements
Scalable Angular 2 Application Architecture
Scalable
communication layer
Communication layer
• RESTful API
• WebSocket application service
• WebRTC data-channel
Various
package formats
Package formats
• RESTful API
• JSON commands
• WebSocket application service
• JSON-RPC
• WebRTC data-channel
• BERT-RPC
Multiple state mutation
sources
Scalable
team
Scalable Angular 2 Application Architecture
Lazy-loading
Dynamic Requirements
Scalable Communication Layer
Various package formats
Multiple state mutation sources
Scalable team
Lazy-loading
Dynamic Requirements
Scalable Communication Layer
Various package formats
Multiple state mutation sources
Scalable team
Lazy-loading
abstraction |əbˈstrakʃ(ə)n|

noun [ mass noun ]
…
4 the process of considering something
independently of its associations or attributes: the
question cannot be considered in abstraction from
the historical context in which it was raised.
WebRTC
Gateway
WebSocket
Gateway
Gateway
WebRTC
Gateway
WebSocket
Gateway
Dynamic Requirements
Scalable Communication Layer
Various package formats
Multiple state mutation sources
Scalable team
Lazy-loading
redux
Dynamic Requirements
Scalable Communication Layer
Various package formats
Multiple state mutation sources
Scalable team
Lazy-loading
Modular
.
src
multi-player
commands
components
gateways
single-player
components
home
components
shared
.
src
multi-player
commands
components
gateways
single-player
components
home
components
shared
/home
.
src
multi-player
commands
components
gateways
single-player
components
home
components
shared
/single-player
.
src
multi-player
commands
components
gateways
single-player
components
home
components
shared
/multi-player
Sample Tech Stack
• Angular 2
• RxJS
• ngrx
• TypeScript
• ImmutableJS
RxJS
in 2 slides
[1, 2, 3]
.map(n => n * 2)
.filter(n => n > 2);
higher-order-functions.ts
let obs = Rx.Observable.create(observer => {
let counter = 0;
setInterval(() => observer.next(counter++), 1000);
});
obs
.map(n => n * 2)
.filter(n => n > 2)
.subscribe(n => console.log(n));
rx.ts
let obs = Rx.Observable.create(observer => {
let counter = 0;
setInterval(() => observer.next(counter++), 1000);
});
obs
.map(n => n * 2)
.filter(n => n > 2)
.subscribe(n => console.log(n));
rx.ts
Sample application
Scalable Angular 2 Application Architecture
Scalable Angular 2 Application Architecture
High-level
Architecture
UI components
Façade
(provides simplified interface to the components)
State management Async services
Gateways
(HTTP, WS, WebRTC)
Commands
(RESTful, RPC)
Payloads
(BERT, JSON)
Store Reducers
UI components
Façade
(provides simplified interface to the components)
State management Async services
Gateways
(HTTP, WS, WebRTC)
Commands
(RESTful, RPC)
Payloads
(BERT, JSON)
Store Reducers
UI components
Façade
(provides simplified interface to the components)
State management Async services
Gateways
(HTTP, WS, WebRTC)
Commands
(RESTful, RPC)
Payloads
(BERT, JSON)
Store Reducers
UI components
Façade
(provides simplified interface to the components)
State management Async services
Gateways
(HTTP, WS, WebRTC)
Commands
(RESTful, RPC)
Payloads
(BERT, JSON)
Store Reducers
UI components
Façade
(provides simplified interface to the components)
State management Async services
Gateways
(HTTP, WS, WebRTC)
Commands
(RESTful, RPC)
Payloads
(BERT, JSON)
Store Reducers
UI components
UI components
Façade
(provides simplified interface to the components)
State management Async services
Gateways
(HTTP, WS, WebRTC)
Commands
(RESTful, RPC)
Payloads
(BERT, JSON)
Store Reducers
export class GameComponent implements AfterViewInit {
@Input() text: string;
@Output() change: EventEmitter<string> …
constructor(private _model: GameModel …) {}
changeHandler(data: string) {
this._model.onProgress(data);
}
get invalid() {
return this._model.game$
.scan((accum: boolean, current: any) => {
return (current && current.get(‘invalid’)
|| accum;
}, false);
}
}
game.component.ts
export class GameComponent implements AfterViewInit {
@Input() text: string;
@Output() change: EventEmitter<string> …
constructor(private _model: GameModel …) {}
changeHandler(data: string) {
this._model.onProgress(data);
}
get invalid() {
return this._model.game$
.scan((accum: boolean, current: any) => {
return (current && current.get(‘invalid’)
|| accum;
}, false);
}
}
game.component.ts
UI components
Façade
(provides simplified interface to the components)
State management Async services
Gateways
(HTTP, WS, WebRTC)
Commands
(RESTful, RPC)
Payloads
(BERT, JSON)
Store Reducers
game.model.ts
@Injectable()
export class GameModel extends Model {
game$: Observable<Game>;
constructor(protected _store: Store<any>,
@Inject(AsyncService) _services) {
super(_services || []);
this.game$ = this._store.select('game');
}
...
completeGame(time: number, text: string) {
const action = GameActions.completeGame(time, text);
this._store.dispatch(action);
this.performAsyncAction(action)
.subscribe(() => console.log('Done!'));
}
}
game.model.ts
@Injectable()
export class GameModel extends Model {
game$: Observable<Game>;
constructor(protected _store: Store<any>,
@Inject(AsyncService) _services) {
super(_services || []);
this.game$ = this._store.select('game');
}
...
completeGame(time: number, text: string) {
const action = GameActions.completeGame(time, text);
this._store.dispatch(action);
this.performAsyncAction(action)
.subscribe(() => console.log('Done!'));
}
}
@Injectable()
export class GameModel extends Model {
game$: Observable<Game>;
constructor(protected _store: Store<any>,
@Inject(AsyncService) _services) {
super(_services || []);
this.game$ = this._store.select('game');
}
...
completeGame(time: number, text: string) {
const action = GameActions.completeGame(time, text);
this._store.dispatch(action);
this.performAsyncAction(action)
.subscribe(() => console.log('Done!'));
}
}
game.model.ts
@Injectable()
export class GameModel extends Model {
game$: Observable<Game>;
constructor(protected _store: Store<any>,
@Inject(AsyncService) _services) {
super(_services || []);
this.game$ = this._store.select('game');
}
...
completeGame(time: number, text: string) {
const action = GameActions.completeGame(time, text);
this._store.dispatch(action);
this.performAsyncAction(action)
.subscribe(() => console.log('Done!'));
}
}
game.model.ts
@Injectable()
export class GameModel extends Model {
game$: Observable<Game>;
constructor(protected _store: Store<any>,
@Inject(AsyncService) _services) {
super(_services || []);
this.game$ = this._store.select('game');
}
...
completeGame(time: number, text: string) {
const action = GameActions.completeGame(time, text);
this._store.dispatch(action);
this.performAsyncAction(action)
.subscribe(() => console.log('Done!'));
}
}
game.model.ts
@Injectable()
export class GameModel extends Model {
game$: Observable<Game>;
constructor(protected _store: Store<any>,
@Inject(AsyncService) _services) {
super(_services || []);
this.game$ = this._store.select('game');
}
...
completeGame(time: number, text: string) {
const action = GameActions.completeGame(time, text);
this._store.dispatch(action);
this.performAsyncAction(action)
.subscribe(() => console.log('Done!'));
}
}
game.model.ts
UI components
Façade
(provides simplified interface to the components)
State management Async services
Gateways
(HTTP, WS, WebRTC)
Commands
(RESTful, RPC)
Payloads
(BERT, JSON)
Store Reducers
Component
Model
Store
Dispatcher
startGame()
dispatch(action)
applyReducers(action, store)
next(state)
Component
Model
Store
Dispatcher
startGame()
dispatch(action)
applyReducers(action, store)
next(state)
game.reducer.ts
export const gameReducer =
(state: any = initialState.get(‘game'),
action: Action) => {
switch (action.type) {
case START_GAME:
state = fromJS({});
break;
case INVALID_GAME:
state = state.set('invalid', true);
break;
case GAME_PROGRESS:
state = state.set(‘currentText',
action.payload.text);
break;
}
return state;
};
game.reducer.ts
export const gameReducer =
(state: any = initialState.get(‘game'),
action: Action) => {
switch (action.type) {
case START_GAME:
state = fromJS({});
break;
case INVALID_GAME:
state = state.set('invalid', true);
break;
case GAME_PROGRESS:
state = state.set(‘currentText',
action.payload.text);
break;
}
return state;
};
game.reducer.ts
export const gameReducer =
(state: any = initialState.get(‘game'),
action: Action) => {
switch (action.type) {
case START_GAME:
state = fromJS({});
break;
case INVALID_GAME:
state = state.set('invalid', true);
break;
case GAME_PROGRESS:
state = state.set(‘currentText',
action.payload.text);
break;
}
return state;
};
game.reducer.ts
export const gameReducer =
(state: any = initialState.get(‘game'),
action: Action) => {
switch (action.type) {
case START_GAME:
state = fromJS({});
break;
case INVALID_GAME:
state = state.set('invalid', true);
break;
case GAME_PROGRESS:
state = state.set(‘currentText',
action.payload.text);
break;
}
return state;
};
Component
Model
Store
Dispatcher
startGame()
dispatch(action)
applyReducers(action, store)
next(state)
game.component.ts
…
get invalid() {
return this._model.game$
.scan((accum: boolean, current: any) => {
return current.get('invalid') || accum;
}, false);
}
…
game.component.ts
…
get invalid() {
return this._model.game$
.scan((accum: boolean, current: any) => {
return current.get('invalid') || accum;
}, false);
}
…
game.component.ts
…
get invalid() {
return this._model.game$
.scan((accum: boolean, current: any) => {
return current.get('invalid') || accum;
}, false);
}
…
game.component.html
…
<div [hide]="!(invalid | async)">
<h1>The game is invalid...</h1>
</div>
…
game.component.html
…
<div [hide]="!(invalid | async)">
<h1>The game is invalid...</h1>
</div>
…
Async Services
UI components
Façade
(provides simplified interface to the components)
State management Async services
Gateways
(HTTP, WS, WebRTC)
Commands
(RESTful, RPC)
Payloads
(BERT, JSON)
Store Reducers
Remote
Service
App
Remote
Service
App
export abstract class AsyncService {
abstract process(data: Action): Observable<any>;
}
base.async-service.ts
export class GameP2PService extends AsyncService {
constructor(private _rtcGateway: WebRTCGateway, private _store: Store) {
_rtcGateway.dataStream
.map((data: any) => JSON.parse(data.toString()))
.subscribe((command: any) => {
switch (command.method) {
case PROGRESS:
_store.dispatch(P2PActions.progress(command.payload.text));
break;
}
});
}
process(action: Action) {
const commandBuilder = buildP2PCommand(action);
if (!commandBuilder) {
console.warn('This command is not supported');
return Observable.create((obs: Observer<any>) => obs.complete());
} else
return commandBuilder(baseCommand).invoke();
}
}
game-p2p.async-service.ts
export class GameP2PService extends AsyncService {
constructor(private _rtcGateway: WebRTCGateway, private _store: Store) {
_rtcGateway.dataStream
.map((data: any) => JSON.parse(data.toString()))
.subscribe((command: any) => {
switch (command.method) {
case PROGRESS:
_store.dispatch(P2PActions.progress(command.payload.text));
break;
}
});
}
process(action: Action) {
const commandBuilder = buildP2PCommand(action);
if (!commandBuilder) {
console.warn('This command is not supported');
return Observable.create((obs: Observer<any>) => obs.complete());
} else
return commandBuilder(baseCommand).invoke();
}
}
game-p2p.async-service.ts
export class GameP2PService extends AsyncService {
constructor(private _rtcGateway: WebRTCGateway, private _store: Store) {
_rtcGateway.dataStream
.map((data: any) => JSON.parse(data.toString()))
.subscribe((command: any) => {
switch (command.method) {
case PROGRESS:
_store.dispatch(P2PActions.progress(command.payload.text));
break;
}
});
}
process(action: Action) {
const commandBuilder = buildP2PCommand(action);
if (!commandBuilder) {
console.warn('This command is not supported');
return Observable.create((obs: Observer<any>) => obs.complete());
} else
return commandBuilder(baseCommand).invoke();
}
}
game-p2p.async-service.ts
But what if…
Model
S1 S2
Model
S1 S2
A
Model
S1 S2
A
Model
S1 S2
A
Model
S1 S2
A
Model
S1 S2
A
Model
S1 S2
A
Immutability
let user = new Map();
user = user.set('name', 'Joe');
// { name: 'Joe' }
console.log(user.toJS());
immutable.js
No
static typing
Immutability or Static Typing
Why not
Both?
export interface IUser {
id?: number;
gender?: number;
email?: string;
}
const userRecord = Immutable.Record({
id: 0,
gender: 0,
email: null
});
export class User extends userRecord implements IUser {
id: number;
gender: number;
email: string;
constructor(config: IUser) {
super(config);
}
}
immutable-records.ts
export interface IUser {
id?: number;
gender?: number;
email?: string;
}
const userRecord = Immutable.Record({
id: 0,
gender: 0,
email: null
});
export class User extends userRecord implements IUser {
id: number;
gender: number;
email: string;
constructor(config: IUser) {
super(config);
}
}
immutable-records.ts
export interface IUser {
id?: number;
gender?: number;
email?: string;
}
const userRecord = Immutable.Record({
id: 0,
gender: 0,
email: null
});
export class User extends userRecord implements IUser {
id: number;
gender: number;
email: string;
constructor(config: IUser) {
super(config);
}
}
immutable-records.ts
export interface IUser {
id?: number;
gender?: number;
email?: string;
}
const userRecord = Immutable.Record({
id: 0,
gender: 0,
email: null
});
export class User extends userRecord implements IUser {
id: number;
gender: number;
email: string;
constructor(config: IUser) {
super(config);
}
}
immutable-records.ts
Scalable Angular 2 Application Architecture
Recap
Async services
Business facade
Business logicCommunication logic
Immutable app state
Component tree
root cmp
sign-up form
user
UserModel
User Action
Creator
signup(data)
signup(data)
RESTful Async
Service
process(action)
userReducer
register()
RESTful
CommandBuilder
build(action)
Restful
Command
Restful Gateway
invoke()
send()
creates()
uses
as user$
uses user$
Stream
Dependency
Action (manipulation/method call)
User registration
user.email = email
user.name = name
Async services
Business facade
Business logicCommunication logic
Immutable app state
Component tree
root cmp
sign-up form
user
UserModel
User Action
Creator
signup(data)
RESTful Async
Service
process(action)
userReducer
register()
RESTful
CommandBuilder
build(action)
Restful
Command
Restful Gateway
invoke()
send()
creates()
uses
as user$
uses user$
Stream
Dependency
Action (manipulation/method call)
User registration
user.email = email
user.name = name
signup(data)
Async services
Business facade
Business logicCommunication logic
Immutable app state
Component tree
root cmp
sign-up form
user
UserModel
User Action
Creator
RESTful Async
Service
process(action)
userReducer
register()
RESTful
CommandBuilder
build(action)
Restful
Command
Restful Gateway
invoke()
send()
creates()
uses
as user$
uses user$
Stream
Dependency
Action (manipulation/method call)
User registration
user.email = email
user.name = name
signup(data)
signup(data)
Async services
Business facade
Business logicCommunication logic
Immutable app state
Component tree
root cmp
sign-up form
user
UserModel
User Action
Creator
RESTful Async
Service
process(action)
userReducer
register()
RESTful
CommandBuilder
build(action)
Restful
Command
Restful Gateway
invoke()
send()
creates()
uses
as user$
uses user$
Stream
Dependency
Action (manipulation/method call)
User registration
user.email = email
user.name = name
signup(data)
signup(data)
Async services
Business facade
Business logicCommunication logic
Immutable app state
Component tree
root cmp
sign-up form
user
UserModel
User Action
Creator
RESTful Async
Service
process(action)
userReducer
register()
RESTful
CommandBuilder
build(action)
Restful
Command
Restful Gateway
invoke()
send()
creates()
uses
as user$
uses user$
Stream
Dependency
Action (manipulation/method call)
User registration
user.email = email
user.name = name
signup(data)
signup(data)
Async services
Business facade
Business logicCommunication logic
Immutable app state
Component tree
root cmp
sign-up form
user
UserModel
User Action
Creator
RESTful Async
Service
process(action)
userReducer
register()
RESTful
CommandBuilder
build(action)
Restful
Command
Restful Gateway
invoke()
send()
creates()
uses
as user$
uses user$
Stream
Dependency
Action (manipulation/method call)
User registration
user.email = email
user.name = name
signup(data)
signup(data)
Async services
Business facade
Business logicCommunication logic
Immutable app state
Component tree
root cmp
sign-up form
user
UserModel
User Action
Creator
RESTful Async
Service
process(action)
userReducer
register()
RESTful
CommandBuilder
build(action)
Restful
Command
Restful Gateway
invoke()
send()
creates()
uses
as user$
uses user$
Stream
Dependency
Action (manipulation/method call)
User registration
user.email = email
user.name = name
signup(data)
signup(data)
Async services
Business facade
Business logicCommunication logic
Immutable app state
Component tree
root cmp
sign-up form
user
UserModel
User Action
Creator
RESTful Async
Service
process(action)
userReducer
register()
RESTful
CommandBuilder
build(action)
Restful
Command
Restful Gateway
invoke()
send()
creates()
uses
as user$
uses user$
Stream
Dependency
Action (manipulation/method call)
User registration
user.email = email
user.name = name
signup(data)
signup(data)
Async services
Business facade
Business logicCommunication logic
Immutable app state
Component tree
root cmp
sign-up form
user
UserModel
User Action
Creator
RESTful Async
Service
process(action)
userReducer
register()
RESTful
CommandBuilder
build(action)
Restful
Command
Restful Gateway
invoke()
send()
creates()
uses
as user$
uses user$
Stream
Dependency
Action (manipulation/method call)
User registration
user.email = email
user.name = name
signup(data)
signup(data)
Async services
Business facade
Business logicCommunication logic
Immutable app state
Component tree
root cmp
sign-up form
user
UserModel
User Action
Creator
signup(data)
RESTful Async
Service
process(action)
userReducer
register()
RESTful
CommandBuilder
build(action)
Restful
Command
Restful Gateway
invoke()
send()
creates()
uses
as user$
uses user$
Stream
Dependency
Action (manipulation/method call)
User registration
user.email = email
user.name = name
signup(data)
Properties…
• Predictable state management
• Testable (easy to mock services thanks to DI)
• Not coupled to any remote service
• Not coupled to any message format
• Model can use different services based on context
• Easy management of async events
Properties…
• Predictable state management
• Testable (easy to mock services thanks to DI)
• Not coupled to any remote service
• Not coupled to any message format
• Model can use different services based on context
• Easy management of async events
Properties…
• Predictable state management
• Testable (easy to mock services thanks to DI)
• Not coupled to any remote service
• Not coupled to any message format
• Model can use different services based on context
• Easy management of async events
Properties…
• Predictable state management
• Testable (easy to mock services thanks to DI)
• Not coupled to any remote service
• Not coupled to any message format
• Model can use different services based on context
• Easy management of async events
Properties…
• Predictable state management
• Testable (easy to mock services thanks to DI)
• Not coupled to any remote service
• Not coupled to any message format
• Model can use different services based on context
• Easy management of async events
Properties…
• Predictable state management
• Testable (easy to mock services thanks to DI)
• Not coupled to any remote service
• Not coupled to any message format
• Model can use different services based on context
• Easy management of async events
Properties…
• Predictable state management
• Testable (easy to mock services thanks to DI)
• Not coupled to any remote service
• Not coupled to any message format
• Model can use different services based on context
• Easy management of async events
Resources
• redux
• ngrx
• Scalable Single-Page Application Architecture
• Demo
Thank you!
github.com/mgechev
twitter.com/mgechev
blog.mgechev.com
Ad

Recommended

Будь первым
Будь первым
FDConf
 
Redux. From twitter hype to production
Redux. From twitter hype to production
FDConf
 
Beautiful code instead of callback hell using ES6 Generators, Koa, Bluebird (...
Beautiful code instead of callback hell using ES6 Generators, Koa, Bluebird (...
andreaslubbe
 
Avoiding Callback Hell with Async.js
Avoiding Callback Hell with Async.js
cacois
 
Callbacks and control flow in Node js
Callbacks and control flow in Node js
Thomas Roch
 
ECMAScript 6 and the Node Driver
ECMAScript 6 and the Node Driver
MongoDB
 
Reactive, component 그리고 angular2
Reactive, component 그리고 angular2
Jeado Ko
 
非同期javascriptの過去と未来
非同期javascriptの過去と未来
Taketoshi 青野健利
 
Unity and WebSockets
Unity and WebSockets
Josh Glover
 
Angular 1 + es6
Angular 1 + es6
장현 한
 
Introduction to asynchronous DB access using Node.js and MongoDB
Introduction to asynchronous DB access using Node.js and MongoDB
Adrien Joly
 
New Design of OneRing
New Design of OneRing
Qiangning Hong
 
Javascript Everywhere From Nose To Tail
Javascript Everywhere From Nose To Tail
Cliffano Subagio
 
Javascript Promises/Q Library
Javascript Promises/Q Library
async_io
 
How NOT to write in Node.js
How NOT to write in Node.js
Piotr Pelczar
 
Ember.js - A JavaScript framework for creating ambitious web applications
Ember.js - A JavaScript framework for creating ambitious web applications
Juliana Lucena
 
Future Decoded - Node.js per sviluppatori .NET
Future Decoded - Node.js per sviluppatori .NET
Gianluca Carucci
 
Node.js - A Quick Tour
Node.js - A Quick Tour
Felix Geisendörfer
 
Async Redux Actions With RxJS - React Rally 2016
Async Redux Actions With RxJS - React Rally 2016
Ben Lesh
 
Apache MXNet Distributed Training Explained In Depth by Viacheslav Kovalevsky...
Apache MXNet Distributed Training Explained In Depth by Viacheslav Kovalevsky...
Big Data Spain
 
Understanding Asynchronous JavaScript
Understanding Asynchronous JavaScript
jnewmanux
 
Asynchronní programování
Asynchronní programování
PeckaDesign.cz
 
Debugging JavaScript with Chrome
Debugging JavaScript with Chrome
Igor Zalutsky
 
JavaScript Engines and Event Loop
JavaScript Engines and Event Loop
Tapan B.K.
 
JS everywhere 2011
JS everywhere 2011
Oleg Podsechin
 
Map kit light
Map kit light
CocoaHeads France
 
D2
D2
taobao.com
 
Node js presentation
Node js presentation
martincabrera
 
"Service Worker: Let Your Web App Feel Like a Native "
"Service Worker: Let Your Web App Feel Like a Native "
FDConf
 
Dart: питание и сила для вашего проекта
Dart: питание и сила для вашего проекта
FDConf
 

More Related Content

What's hot (20)

Unity and WebSockets
Unity and WebSockets
Josh Glover
 
Angular 1 + es6
Angular 1 + es6
장현 한
 
Introduction to asynchronous DB access using Node.js and MongoDB
Introduction to asynchronous DB access using Node.js and MongoDB
Adrien Joly
 
New Design of OneRing
New Design of OneRing
Qiangning Hong
 
Javascript Everywhere From Nose To Tail
Javascript Everywhere From Nose To Tail
Cliffano Subagio
 
Javascript Promises/Q Library
Javascript Promises/Q Library
async_io
 
How NOT to write in Node.js
How NOT to write in Node.js
Piotr Pelczar
 
Ember.js - A JavaScript framework for creating ambitious web applications
Ember.js - A JavaScript framework for creating ambitious web applications
Juliana Lucena
 
Future Decoded - Node.js per sviluppatori .NET
Future Decoded - Node.js per sviluppatori .NET
Gianluca Carucci
 
Node.js - A Quick Tour
Node.js - A Quick Tour
Felix Geisendörfer
 
Async Redux Actions With RxJS - React Rally 2016
Async Redux Actions With RxJS - React Rally 2016
Ben Lesh
 
Apache MXNet Distributed Training Explained In Depth by Viacheslav Kovalevsky...
Apache MXNet Distributed Training Explained In Depth by Viacheslav Kovalevsky...
Big Data Spain
 
Understanding Asynchronous JavaScript
Understanding Asynchronous JavaScript
jnewmanux
 
Asynchronní programování
Asynchronní programování
PeckaDesign.cz
 
Debugging JavaScript with Chrome
Debugging JavaScript with Chrome
Igor Zalutsky
 
JavaScript Engines and Event Loop
JavaScript Engines and Event Loop
Tapan B.K.
 
JS everywhere 2011
JS everywhere 2011
Oleg Podsechin
 
Map kit light
Map kit light
CocoaHeads France
 
D2
D2
taobao.com
 
Node js presentation
Node js presentation
martincabrera
 
Unity and WebSockets
Unity and WebSockets
Josh Glover
 
Angular 1 + es6
Angular 1 + es6
장현 한
 
Introduction to asynchronous DB access using Node.js and MongoDB
Introduction to asynchronous DB access using Node.js and MongoDB
Adrien Joly
 
Javascript Everywhere From Nose To Tail
Javascript Everywhere From Nose To Tail
Cliffano Subagio
 
Javascript Promises/Q Library
Javascript Promises/Q Library
async_io
 
How NOT to write in Node.js
How NOT to write in Node.js
Piotr Pelczar
 
Ember.js - A JavaScript framework for creating ambitious web applications
Ember.js - A JavaScript framework for creating ambitious web applications
Juliana Lucena
 
Future Decoded - Node.js per sviluppatori .NET
Future Decoded - Node.js per sviluppatori .NET
Gianluca Carucci
 
Async Redux Actions With RxJS - React Rally 2016
Async Redux Actions With RxJS - React Rally 2016
Ben Lesh
 
Apache MXNet Distributed Training Explained In Depth by Viacheslav Kovalevsky...
Apache MXNet Distributed Training Explained In Depth by Viacheslav Kovalevsky...
Big Data Spain
 
Understanding Asynchronous JavaScript
Understanding Asynchronous JavaScript
jnewmanux
 
Asynchronní programování
Asynchronní programování
PeckaDesign.cz
 
Debugging JavaScript with Chrome
Debugging JavaScript with Chrome
Igor Zalutsky
 
JavaScript Engines and Event Loop
JavaScript Engines and Event Loop
Tapan B.K.
 
Node js presentation
Node js presentation
martincabrera
 

Viewers also liked (20)

"Service Worker: Let Your Web App Feel Like a Native "
"Service Worker: Let Your Web App Feel Like a Native "
FDConf
 
Dart: питание и сила для вашего проекта
Dart: питание и сила для вашего проекта
FDConf
 
Migrate your React.js application from (m)Observable to Redux
Migrate your React.js application from (m)Observable to Redux
FDConf
 
Если у вас нету тестов...
Если у вас нету тестов...
FDConf
 
CSSO — сжимаем CSS
CSSO — сжимаем CSS
FDConf
 
"Пиринговый веб на JavaScript"
"Пиринговый веб на JavaScript"
FDConf
 
JavaScript: прошлое, настоящее и будущее.
JavaScript: прошлое, настоящее и будущее.
FDConf
 
В погоне за производительностью
В погоне за производительностью
Denys Mishunov
 
AngularJS application architecture
AngularJS application architecture
Gabriele Falace
 
Single Page Application (SPA) using AngularJS
Single Page Application (SPA) using AngularJS
M R Rony
 
AngularJS Architecture
AngularJS Architecture
Eyal Vardi
 
Securing your AngularJS Application
Securing your AngularJS Application
Philippe De Ryck
 
Angularjs architecture
Angularjs architecture
Michael He
 
Knowledge share about scalable application architecture
Knowledge share about scalable application architecture
AHM Pervej Kabir
 
Service workers
Service workers
jungkees
 
Digital pipeline — инновации в продажах / Михаил Токовинин
Digital pipeline — инновации в продажах / Михаил Токовинин
Ontico
 
Service workers your applications never felt so good
Service workers your applications never felt so good
Chris Love
 
AngularJS - Architecture decisions in a large project 
AngularJS - Architecture decisions in a large project 
Elad Hirsch
 
Building an End-to-End AngularJS Application
Building an End-to-End AngularJS Application
Dan Wahlin
 
Service Workers for Performance
Service Workers for Performance
Patrick Meenan
 
"Service Worker: Let Your Web App Feel Like a Native "
"Service Worker: Let Your Web App Feel Like a Native "
FDConf
 
Dart: питание и сила для вашего проекта
Dart: питание и сила для вашего проекта
FDConf
 
Migrate your React.js application from (m)Observable to Redux
Migrate your React.js application from (m)Observable to Redux
FDConf
 
Если у вас нету тестов...
Если у вас нету тестов...
FDConf
 
CSSO — сжимаем CSS
CSSO — сжимаем CSS
FDConf
 
"Пиринговый веб на JavaScript"
"Пиринговый веб на JavaScript"
FDConf
 
JavaScript: прошлое, настоящее и будущее.
JavaScript: прошлое, настоящее и будущее.
FDConf
 
В погоне за производительностью
В погоне за производительностью
Denys Mishunov
 
AngularJS application architecture
AngularJS application architecture
Gabriele Falace
 
Single Page Application (SPA) using AngularJS
Single Page Application (SPA) using AngularJS
M R Rony
 
AngularJS Architecture
AngularJS Architecture
Eyal Vardi
 
Securing your AngularJS Application
Securing your AngularJS Application
Philippe De Ryck
 
Angularjs architecture
Angularjs architecture
Michael He
 
Knowledge share about scalable application architecture
Knowledge share about scalable application architecture
AHM Pervej Kabir
 
Service workers
Service workers
jungkees
 
Digital pipeline — инновации в продажах / Михаил Токовинин
Digital pipeline — инновации в продажах / Михаил Токовинин
Ontico
 
Service workers your applications never felt so good
Service workers your applications never felt so good
Chris Love
 
AngularJS - Architecture decisions in a large project 
AngularJS - Architecture decisions in a large project 
Elad Hirsch
 
Building an End-to-End AngularJS Application
Building an End-to-End AngularJS Application
Dan Wahlin
 
Service Workers for Performance
Service Workers for Performance
Patrick Meenan
 
Ad

Similar to Scalable Angular 2 Application Architecture (20)

Low Latency Networking on IOS and Android over Cloud by Oguz Bastemur
Low Latency Networking on IOS and Android over Cloud by Oguz Bastemur
Codemotion
 
ngGoBuilder and collaborative development between San Francisco and Tokyo
ngGoBuilder and collaborative development between San Francisco and Tokyo
notolab
 
Rest on steroids
Rest on steroids
fds2
 
NGRX Apps in Depth
NGRX Apps in Depth
Trayan Iliev
 
Microservices with .Net - NDC Sydney, 2016
Microservices with .Net - NDC Sydney, 2016
Richard Banks
 
Building fast,scalable game server in node.js
Building fast,scalable game server in node.js
Xie ChengChao
 
ngServer and-collaboratived-development-between-san-francisco-and-tokyo
ngServer and-collaboratived-development-between-san-francisco-and-tokyo
Satoshi Tanaka
 
Ngrx slides
Ngrx slides
Christoffer Noring
 
Flow Base Programming with Node-RED and Functional Reactive Programming with ...
Flow Base Programming with Node-RED and Functional Reactive Programming with ...
Sven Beauprez
 
ASP.NET Core 3.0 Deep Dive
ASP.NET Core 3.0 Deep Dive
Jon Galloway
 
Asynchronous single page applications without a line of HTML or Javascript, o...
Asynchronous single page applications without a line of HTML or Javascript, o...
Robert Schadek
 
Unity networking
Unity networking
Minh Tuan
 
REST to JavaScript for Better Client-side Development
REST to JavaScript for Better Client-side Development
Hyunghun Cho
 
Kinh nghiệm phát triển Captain Strike
Kinh nghiệm phát triển Captain Strike
GameLandVN
 
Captain strike backend post-mortem
Captain strike backend post-mortem
JOY Entertainment
 
Realtime html5 multiplayer_games_with_node_js
Realtime html5 multiplayer_games_with_node_js
Mario Gonzalez
 
Functional Programming with Streams in node.js
Functional Programming with Streams in node.js
Adam Crabtree
 
Building Killer RESTful APIs with NodeJs
Building Killer RESTful APIs with NodeJs
Srdjan Strbanovic
 
Play! with rest
Play! with rest
Gregor Trefs
 
Multi-Process JavaScript Architectures
Multi-Process JavaScript Architectures
Mark Trostler
 
Low Latency Networking on IOS and Android over Cloud by Oguz Bastemur
Low Latency Networking on IOS and Android over Cloud by Oguz Bastemur
Codemotion
 
ngGoBuilder and collaborative development between San Francisco and Tokyo
ngGoBuilder and collaborative development between San Francisco and Tokyo
notolab
 
Rest on steroids
Rest on steroids
fds2
 
NGRX Apps in Depth
NGRX Apps in Depth
Trayan Iliev
 
Microservices with .Net - NDC Sydney, 2016
Microservices with .Net - NDC Sydney, 2016
Richard Banks
 
Building fast,scalable game server in node.js
Building fast,scalable game server in node.js
Xie ChengChao
 
ngServer and-collaboratived-development-between-san-francisco-and-tokyo
ngServer and-collaboratived-development-between-san-francisco-and-tokyo
Satoshi Tanaka
 
Flow Base Programming with Node-RED and Functional Reactive Programming with ...
Flow Base Programming with Node-RED and Functional Reactive Programming with ...
Sven Beauprez
 
ASP.NET Core 3.0 Deep Dive
ASP.NET Core 3.0 Deep Dive
Jon Galloway
 
Asynchronous single page applications without a line of HTML or Javascript, o...
Asynchronous single page applications without a line of HTML or Javascript, o...
Robert Schadek
 
Unity networking
Unity networking
Minh Tuan
 
REST to JavaScript for Better Client-side Development
REST to JavaScript for Better Client-side Development
Hyunghun Cho
 
Kinh nghiệm phát triển Captain Strike
Kinh nghiệm phát triển Captain Strike
GameLandVN
 
Captain strike backend post-mortem
Captain strike backend post-mortem
JOY Entertainment
 
Realtime html5 multiplayer_games_with_node_js
Realtime html5 multiplayer_games_with_node_js
Mario Gonzalez
 
Functional Programming with Streams in node.js
Functional Programming with Streams in node.js
Adam Crabtree
 
Building Killer RESTful APIs with NodeJs
Building Killer RESTful APIs with NodeJs
Srdjan Strbanovic
 
Multi-Process JavaScript Architectures
Multi-Process JavaScript Architectures
Mark Trostler
 
Ad

More from FDConf (20)

Антон Киршанов - «Квант изменения. Реактивные реакции на React.
Антон Киршанов - «Квант изменения. Реактивные реакции на React.
FDConf
 
Игорь Еростенко - Создаем виртуальный тур
Игорь Еростенко - Создаем виртуальный тур
FDConf
 
Илья Климов - Reason: маргиналы против хайпа
Илья Климов - Reason: маргиналы против хайпа
FDConf
 
Максим Щепелин - Доставляя веб-контент в игру
Максим Щепелин - Доставляя веб-контент в игру
FDConf
 
Александр Черноокий - Как правило "победитель получает все" работает и не раб...
Александр Черноокий - Как правило "победитель получает все" работает и не раб...
FDConf
 
Михаил Волчек - Что такое Цифровая мастерская?
Михаил Волчек - Что такое Цифровая мастерская?
FDConf
 
Radoslav Stankov - Handling GraphQL with React and Apollo
Radoslav Stankov - Handling GraphQL with React and Apollo
FDConf
 
Виктор Русакович - Выборы, выборы, все фреймворки… приторны
Виктор Русакович - Выборы, выборы, все фреймворки… приторны
FDConf
 
Slobodan Stojanovic - 8 1/2 things about serverless
Slobodan Stojanovic - 8 1/2 things about serverless
FDConf
 
Тимофей Лавренюк - Почему мне зашел PWA?
Тимофей Лавренюк - Почему мне зашел PWA?
FDConf
 
В погоне за производительностью
В погоне за производительностью
FDConf
 
«I knew there had to be a better way to build mobile app»​
«I knew there had to be a better way to build mobile app»​
FDConf
 
«Как перестать отлаживать асинхронные вызовы и начать жить»​
«Как перестать отлаживать асинхронные вызовы и начать жить»​
FDConf
 
«Continuous Integration — A to Z или Непрерывная интеграция — кто всё сломал?»
«Continuous Integration — A to Z или Непрерывная интеграция — кто всё сломал?»
FDConf
 
«Идеи и алгоритмы создания масштабируемой архитектуры в играх»​
«Идеи и алгоритмы создания масштабируемой архитектуры в играх»​
FDConf
 
«От экспериментов с инфраструктурой до внедрения в продакшен»​
«От экспериментов с инфраструктурой до внедрения в продакшен»​
FDConf
 
«The Grail: React based Isomorph apps framework»​
«The Grail: React based Isomorph apps framework»​
FDConf
 
«The Illusion of Time. When 60 sec is not 1 minute»​
«The Illusion of Time. When 60 sec is not 1 minute»​
FDConf
 
«Книги в браузере»
«Книги в браузере»
FDConf
 
«Как работают современные интерактивные карты на WebGL»​
«Как работают современные интерактивные карты на WebGL»​
FDConf
 
Антон Киршанов - «Квант изменения. Реактивные реакции на React.
Антон Киршанов - «Квант изменения. Реактивные реакции на React.
FDConf
 
Игорь Еростенко - Создаем виртуальный тур
Игорь Еростенко - Создаем виртуальный тур
FDConf
 
Илья Климов - Reason: маргиналы против хайпа
Илья Климов - Reason: маргиналы против хайпа
FDConf
 
Максим Щепелин - Доставляя веб-контент в игру
Максим Щепелин - Доставляя веб-контент в игру
FDConf
 
Александр Черноокий - Как правило "победитель получает все" работает и не раб...
Александр Черноокий - Как правило "победитель получает все" работает и не раб...
FDConf
 
Михаил Волчек - Что такое Цифровая мастерская?
Михаил Волчек - Что такое Цифровая мастерская?
FDConf
 
Radoslav Stankov - Handling GraphQL with React and Apollo
Radoslav Stankov - Handling GraphQL with React and Apollo
FDConf
 
Виктор Русакович - Выборы, выборы, все фреймворки… приторны
Виктор Русакович - Выборы, выборы, все фреймворки… приторны
FDConf
 
Slobodan Stojanovic - 8 1/2 things about serverless
Slobodan Stojanovic - 8 1/2 things about serverless
FDConf
 
Тимофей Лавренюк - Почему мне зашел PWA?
Тимофей Лавренюк - Почему мне зашел PWA?
FDConf
 
В погоне за производительностью
В погоне за производительностью
FDConf
 
«I knew there had to be a better way to build mobile app»​
«I knew there had to be a better way to build mobile app»​
FDConf
 
«Как перестать отлаживать асинхронные вызовы и начать жить»​
«Как перестать отлаживать асинхронные вызовы и начать жить»​
FDConf
 
«Continuous Integration — A to Z или Непрерывная интеграция — кто всё сломал?»
«Continuous Integration — A to Z или Непрерывная интеграция — кто всё сломал?»
FDConf
 
«Идеи и алгоритмы создания масштабируемой архитектуры в играх»​
«Идеи и алгоритмы создания масштабируемой архитектуры в играх»​
FDConf
 
«От экспериментов с инфраструктурой до внедрения в продакшен»​
«От экспериментов с инфраструктурой до внедрения в продакшен»​
FDConf
 
«The Grail: React based Isomorph apps framework»​
«The Grail: React based Isomorph apps framework»​
FDConf
 
«The Illusion of Time. When 60 sec is not 1 minute»​
«The Illusion of Time. When 60 sec is not 1 minute»​
FDConf
 
«Книги в браузере»
«Книги в браузере»
FDConf
 
«Как работают современные интерактивные карты на WebGL»​
«Как работают современные интерактивные карты на WebGL»​
FDConf
 

Recently uploaded (20)

Paper 109 | Archetypal Journeys in ‘Interstellar’: Exploring Universal Themes...
Paper 109 | Archetypal Journeys in ‘Interstellar’: Exploring Universal Themes...
Rajdeep Bavaliya
 
Satluj House Semi Final Quiz Quencher 2025.pptx
Satluj House Semi Final Quiz Quencher 2025.pptx
148CDivyamDubey
 
2025 June Year 9 Presentation: Subject selection.pptx
2025 June Year 9 Presentation: Subject selection.pptx
mansk2
 
Basic English for Communication - Dr Hj Euis Eti Rohaeti Mpd
Basic English for Communication - Dr Hj Euis Eti Rohaeti Mpd
Restu Bias Primandhika
 
What is FIle and explanation of text files.pptx
What is FIle and explanation of text files.pptx
Ramakrishna Reddy Bijjam
 
ROLE PLAY: FIRST AID -CPR & RECOVERY POSITION.pptx
ROLE PLAY: FIRST AID -CPR & RECOVERY POSITION.pptx
Belicia R.S
 
Birnagar High School Platinum Jubilee Quiz.pptx
Birnagar High School Platinum Jubilee Quiz.pptx
Sourav Kr Podder
 
LDMMIA Practitioner Level Orientation Updates
LDMMIA Practitioner Level Orientation Updates
LDM & Mia eStudios
 
SCHIZOPHRENIA OTHER PSYCHOTIC DISORDER LIKE Persistent delusion/Capgras syndr...
SCHIZOPHRENIA OTHER PSYCHOTIC DISORDER LIKE Persistent delusion/Capgras syndr...
parmarjuli1412
 
Ray Dalio How Countries go Broke the Big Cycle
Ray Dalio How Countries go Broke the Big Cycle
Dadang Solihin
 
YSPH VMOC Special Report - Measles Outbreak Southwest US 6-14-2025.pptx
YSPH VMOC Special Report - Measles Outbreak Southwest US 6-14-2025.pptx
Yale School of Public Health - The Virtual Medical Operations Center (VMOC)
 
Introduction to problem solving Techniques
Introduction to problem solving Techniques
merlinjohnsy
 
“THE BEST CLASS IN SCHOOL”. _
“THE BEST CLASS IN SCHOOL”. _
Colégio Santa Teresinha
 
Health Care Planning and Organization of Health Care at Various Levels – Unit...
Health Care Planning and Organization of Health Care at Various Levels – Unit...
RAKESH SAJJAN
 
University of Ghana Cracks Down on Misconduct: Over 100 Students Sanctioned
University of Ghana Cracks Down on Misconduct: Over 100 Students Sanctioned
Kweku Zurek
 
GEOGRAPHY-Study Material [ Class 10th] .pdf
GEOGRAPHY-Study Material [ Class 10th] .pdf
SHERAZ AHMAD LONE
 
Pests of Maize: An comprehensive overview.pptx
Pests of Maize: An comprehensive overview.pptx
Arshad Shaikh
 
LDMMIA Practitioner Student Reiki Yoga S2 Video PDF Without Yogi Goddess
LDMMIA Practitioner Student Reiki Yoga S2 Video PDF Without Yogi Goddess
LDM & Mia eStudios
 
LAZY SUNDAY QUIZ "A GENERAL QUIZ" JUNE 2025 SMC QUIZ CLUB, SILCHAR MEDICAL CO...
LAZY SUNDAY QUIZ "A GENERAL QUIZ" JUNE 2025 SMC QUIZ CLUB, SILCHAR MEDICAL CO...
Ultimatewinner0342
 
Paper 107 | From Watchdog to Lapdog: Ishiguro’s Fiction and the Rise of “Godi...
Paper 107 | From Watchdog to Lapdog: Ishiguro’s Fiction and the Rise of “Godi...
Rajdeep Bavaliya
 
Paper 109 | Archetypal Journeys in ‘Interstellar’: Exploring Universal Themes...
Paper 109 | Archetypal Journeys in ‘Interstellar’: Exploring Universal Themes...
Rajdeep Bavaliya
 
Satluj House Semi Final Quiz Quencher 2025.pptx
Satluj House Semi Final Quiz Quencher 2025.pptx
148CDivyamDubey
 
2025 June Year 9 Presentation: Subject selection.pptx
2025 June Year 9 Presentation: Subject selection.pptx
mansk2
 
Basic English for Communication - Dr Hj Euis Eti Rohaeti Mpd
Basic English for Communication - Dr Hj Euis Eti Rohaeti Mpd
Restu Bias Primandhika
 
What is FIle and explanation of text files.pptx
What is FIle and explanation of text files.pptx
Ramakrishna Reddy Bijjam
 
ROLE PLAY: FIRST AID -CPR & RECOVERY POSITION.pptx
ROLE PLAY: FIRST AID -CPR & RECOVERY POSITION.pptx
Belicia R.S
 
Birnagar High School Platinum Jubilee Quiz.pptx
Birnagar High School Platinum Jubilee Quiz.pptx
Sourav Kr Podder
 
LDMMIA Practitioner Level Orientation Updates
LDMMIA Practitioner Level Orientation Updates
LDM & Mia eStudios
 
SCHIZOPHRENIA OTHER PSYCHOTIC DISORDER LIKE Persistent delusion/Capgras syndr...
SCHIZOPHRENIA OTHER PSYCHOTIC DISORDER LIKE Persistent delusion/Capgras syndr...
parmarjuli1412
 
Ray Dalio How Countries go Broke the Big Cycle
Ray Dalio How Countries go Broke the Big Cycle
Dadang Solihin
 
Introduction to problem solving Techniques
Introduction to problem solving Techniques
merlinjohnsy
 
Health Care Planning and Organization of Health Care at Various Levels – Unit...
Health Care Planning and Organization of Health Care at Various Levels – Unit...
RAKESH SAJJAN
 
University of Ghana Cracks Down on Misconduct: Over 100 Students Sanctioned
University of Ghana Cracks Down on Misconduct: Over 100 Students Sanctioned
Kweku Zurek
 
GEOGRAPHY-Study Material [ Class 10th] .pdf
GEOGRAPHY-Study Material [ Class 10th] .pdf
SHERAZ AHMAD LONE
 
Pests of Maize: An comprehensive overview.pptx
Pests of Maize: An comprehensive overview.pptx
Arshad Shaikh
 
LDMMIA Practitioner Student Reiki Yoga S2 Video PDF Without Yogi Goddess
LDMMIA Practitioner Student Reiki Yoga S2 Video PDF Without Yogi Goddess
LDM & Mia eStudios
 
LAZY SUNDAY QUIZ "A GENERAL QUIZ" JUNE 2025 SMC QUIZ CLUB, SILCHAR MEDICAL CO...
LAZY SUNDAY QUIZ "A GENERAL QUIZ" JUNE 2025 SMC QUIZ CLUB, SILCHAR MEDICAL CO...
Ultimatewinner0342
 
Paper 107 | From Watchdog to Lapdog: Ishiguro’s Fiction and the Rise of “Godi...
Paper 107 | From Watchdog to Lapdog: Ishiguro’s Fiction and the Rise of “Godi...
Rajdeep Bavaliya
 

Scalable Angular 2 Application Architecture

  • 7. – Martin Fowler “…decisions that are hard to change…” Architecture
  • 12. Communication layer • RESTful API • WebSocket application service • WebRTC data-channel
  • 14. Package formats • RESTful API • JSON commands • WebSocket application service • JSON-RPC • WebRTC data-channel • BERT-RPC
  • 19. Dynamic Requirements Scalable Communication Layer Various package formats Multiple state mutation sources Scalable team Lazy-loading
  • 20. Dynamic Requirements Scalable Communication Layer Various package formats Multiple state mutation sources Scalable team Lazy-loading
  • 21. abstraction |əbˈstrakʃ(ə)n| noun [ mass noun ] … 4 the process of considering something independently of its associations or attributes: the question cannot be considered in abstraction from the historical context in which it was raised.
  • 24. Dynamic Requirements Scalable Communication Layer Various package formats Multiple state mutation sources Scalable team Lazy-loading
  • 25. redux
  • 26. Dynamic Requirements Scalable Communication Layer Various package formats Multiple state mutation sources Scalable team Lazy-loading
  • 32. Sample Tech Stack • Angular 2 • RxJS • ngrx • TypeScript • ImmutableJS
  • 34. [1, 2, 3] .map(n => n * 2) .filter(n => n > 2); higher-order-functions.ts
  • 35. let obs = Rx.Observable.create(observer => { let counter = 0; setInterval(() => observer.next(counter++), 1000); }); obs .map(n => n * 2) .filter(n => n > 2) .subscribe(n => console.log(n)); rx.ts
  • 36. let obs = Rx.Observable.create(observer => { let counter = 0; setInterval(() => observer.next(counter++), 1000); }); obs .map(n => n * 2) .filter(n => n > 2) .subscribe(n => console.log(n)); rx.ts
  • 41. UI components Façade (provides simplified interface to the components) State management Async services Gateways (HTTP, WS, WebRTC) Commands (RESTful, RPC) Payloads (BERT, JSON) Store Reducers
  • 42. UI components Façade (provides simplified interface to the components) State management Async services Gateways (HTTP, WS, WebRTC) Commands (RESTful, RPC) Payloads (BERT, JSON) Store Reducers
  • 43. UI components Façade (provides simplified interface to the components) State management Async services Gateways (HTTP, WS, WebRTC) Commands (RESTful, RPC) Payloads (BERT, JSON) Store Reducers
  • 44. UI components Façade (provides simplified interface to the components) State management Async services Gateways (HTTP, WS, WebRTC) Commands (RESTful, RPC) Payloads (BERT, JSON) Store Reducers
  • 45. UI components Façade (provides simplified interface to the components) State management Async services Gateways (HTTP, WS, WebRTC) Commands (RESTful, RPC) Payloads (BERT, JSON) Store Reducers
  • 47. UI components Façade (provides simplified interface to the components) State management Async services Gateways (HTTP, WS, WebRTC) Commands (RESTful, RPC) Payloads (BERT, JSON) Store Reducers
  • 48. export class GameComponent implements AfterViewInit { @Input() text: string; @Output() change: EventEmitter<string> … constructor(private _model: GameModel …) {} changeHandler(data: string) { this._model.onProgress(data); } get invalid() { return this._model.game$ .scan((accum: boolean, current: any) => { return (current && current.get(‘invalid’) || accum; }, false); } } game.component.ts
  • 49. export class GameComponent implements AfterViewInit { @Input() text: string; @Output() change: EventEmitter<string> … constructor(private _model: GameModel …) {} changeHandler(data: string) { this._model.onProgress(data); } get invalid() { return this._model.game$ .scan((accum: boolean, current: any) => { return (current && current.get(‘invalid’) || accum; }, false); } } game.component.ts
  • 50. UI components Façade (provides simplified interface to the components) State management Async services Gateways (HTTP, WS, WebRTC) Commands (RESTful, RPC) Payloads (BERT, JSON) Store Reducers
  • 51. game.model.ts @Injectable() export class GameModel extends Model { game$: Observable<Game>; constructor(protected _store: Store<any>, @Inject(AsyncService) _services) { super(_services || []); this.game$ = this._store.select('game'); } ... completeGame(time: number, text: string) { const action = GameActions.completeGame(time, text); this._store.dispatch(action); this.performAsyncAction(action) .subscribe(() => console.log('Done!')); } }
  • 52. game.model.ts @Injectable() export class GameModel extends Model { game$: Observable<Game>; constructor(protected _store: Store<any>, @Inject(AsyncService) _services) { super(_services || []); this.game$ = this._store.select('game'); } ... completeGame(time: number, text: string) { const action = GameActions.completeGame(time, text); this._store.dispatch(action); this.performAsyncAction(action) .subscribe(() => console.log('Done!')); } }
  • 53. @Injectable() export class GameModel extends Model { game$: Observable<Game>; constructor(protected _store: Store<any>, @Inject(AsyncService) _services) { super(_services || []); this.game$ = this._store.select('game'); } ... completeGame(time: number, text: string) { const action = GameActions.completeGame(time, text); this._store.dispatch(action); this.performAsyncAction(action) .subscribe(() => console.log('Done!')); } } game.model.ts
  • 54. @Injectable() export class GameModel extends Model { game$: Observable<Game>; constructor(protected _store: Store<any>, @Inject(AsyncService) _services) { super(_services || []); this.game$ = this._store.select('game'); } ... completeGame(time: number, text: string) { const action = GameActions.completeGame(time, text); this._store.dispatch(action); this.performAsyncAction(action) .subscribe(() => console.log('Done!')); } } game.model.ts
  • 55. @Injectable() export class GameModel extends Model { game$: Observable<Game>; constructor(protected _store: Store<any>, @Inject(AsyncService) _services) { super(_services || []); this.game$ = this._store.select('game'); } ... completeGame(time: number, text: string) { const action = GameActions.completeGame(time, text); this._store.dispatch(action); this.performAsyncAction(action) .subscribe(() => console.log('Done!')); } } game.model.ts
  • 56. @Injectable() export class GameModel extends Model { game$: Observable<Game>; constructor(protected _store: Store<any>, @Inject(AsyncService) _services) { super(_services || []); this.game$ = this._store.select('game'); } ... completeGame(time: number, text: string) { const action = GameActions.completeGame(time, text); this._store.dispatch(action); this.performAsyncAction(action) .subscribe(() => console.log('Done!')); } } game.model.ts
  • 57. UI components Façade (provides simplified interface to the components) State management Async services Gateways (HTTP, WS, WebRTC) Commands (RESTful, RPC) Payloads (BERT, JSON) Store Reducers
  • 60. game.reducer.ts export const gameReducer = (state: any = initialState.get(‘game'), action: Action) => { switch (action.type) { case START_GAME: state = fromJS({}); break; case INVALID_GAME: state = state.set('invalid', true); break; case GAME_PROGRESS: state = state.set(‘currentText', action.payload.text); break; } return state; };
  • 61. game.reducer.ts export const gameReducer = (state: any = initialState.get(‘game'), action: Action) => { switch (action.type) { case START_GAME: state = fromJS({}); break; case INVALID_GAME: state = state.set('invalid', true); break; case GAME_PROGRESS: state = state.set(‘currentText', action.payload.text); break; } return state; };
  • 62. game.reducer.ts export const gameReducer = (state: any = initialState.get(‘game'), action: Action) => { switch (action.type) { case START_GAME: state = fromJS({}); break; case INVALID_GAME: state = state.set('invalid', true); break; case GAME_PROGRESS: state = state.set(‘currentText', action.payload.text); break; } return state; };
  • 63. game.reducer.ts export const gameReducer = (state: any = initialState.get(‘game'), action: Action) => { switch (action.type) { case START_GAME: state = fromJS({}); break; case INVALID_GAME: state = state.set('invalid', true); break; case GAME_PROGRESS: state = state.set(‘currentText', action.payload.text); break; } return state; };
  • 65. game.component.ts … get invalid() { return this._model.game$ .scan((accum: boolean, current: any) => { return current.get('invalid') || accum; }, false); } …
  • 66. game.component.ts … get invalid() { return this._model.game$ .scan((accum: boolean, current: any) => { return current.get('invalid') || accum; }, false); } …
  • 67. game.component.ts … get invalid() { return this._model.game$ .scan((accum: boolean, current: any) => { return current.get('invalid') || accum; }, false); } …
  • 68. game.component.html … <div [hide]="!(invalid | async)"> <h1>The game is invalid...</h1> </div> …
  • 69. game.component.html … <div [hide]="!(invalid | async)"> <h1>The game is invalid...</h1> </div> …
  • 71. UI components Façade (provides simplified interface to the components) State management Async services Gateways (HTTP, WS, WebRTC) Commands (RESTful, RPC) Payloads (BERT, JSON) Store Reducers
  • 74. export abstract class AsyncService { abstract process(data: Action): Observable<any>; } base.async-service.ts
  • 75. export class GameP2PService extends AsyncService { constructor(private _rtcGateway: WebRTCGateway, private _store: Store) { _rtcGateway.dataStream .map((data: any) => JSON.parse(data.toString())) .subscribe((command: any) => { switch (command.method) { case PROGRESS: _store.dispatch(P2PActions.progress(command.payload.text)); break; } }); } process(action: Action) { const commandBuilder = buildP2PCommand(action); if (!commandBuilder) { console.warn('This command is not supported'); return Observable.create((obs: Observer<any>) => obs.complete()); } else return commandBuilder(baseCommand).invoke(); } } game-p2p.async-service.ts
  • 76. export class GameP2PService extends AsyncService { constructor(private _rtcGateway: WebRTCGateway, private _store: Store) { _rtcGateway.dataStream .map((data: any) => JSON.parse(data.toString())) .subscribe((command: any) => { switch (command.method) { case PROGRESS: _store.dispatch(P2PActions.progress(command.payload.text)); break; } }); } process(action: Action) { const commandBuilder = buildP2PCommand(action); if (!commandBuilder) { console.warn('This command is not supported'); return Observable.create((obs: Observer<any>) => obs.complete()); } else return commandBuilder(baseCommand).invoke(); } } game-p2p.async-service.ts
  • 77. export class GameP2PService extends AsyncService { constructor(private _rtcGateway: WebRTCGateway, private _store: Store) { _rtcGateway.dataStream .map((data: any) => JSON.parse(data.toString())) .subscribe((command: any) => { switch (command.method) { case PROGRESS: _store.dispatch(P2PActions.progress(command.payload.text)); break; } }); } process(action: Action) { const commandBuilder = buildP2PCommand(action); if (!commandBuilder) { console.warn('This command is not supported'); return Observable.create((obs: Observer<any>) => obs.complete()); } else return commandBuilder(baseCommand).invoke(); } } game-p2p.async-service.ts
  • 87. let user = new Map(); user = user.set('name', 'Joe'); // { name: 'Joe' } console.log(user.toJS()); immutable.js
  • 91. export interface IUser { id?: number; gender?: number; email?: string; } const userRecord = Immutable.Record({ id: 0, gender: 0, email: null }); export class User extends userRecord implements IUser { id: number; gender: number; email: string; constructor(config: IUser) { super(config); } } immutable-records.ts
  • 92. export interface IUser { id?: number; gender?: number; email?: string; } const userRecord = Immutable.Record({ id: 0, gender: 0, email: null }); export class User extends userRecord implements IUser { id: number; gender: number; email: string; constructor(config: IUser) { super(config); } } immutable-records.ts
  • 93. export interface IUser { id?: number; gender?: number; email?: string; } const userRecord = Immutable.Record({ id: 0, gender: 0, email: null }); export class User extends userRecord implements IUser { id: number; gender: number; email: string; constructor(config: IUser) { super(config); } } immutable-records.ts
  • 94. export interface IUser { id?: number; gender?: number; email?: string; } const userRecord = Immutable.Record({ id: 0, gender: 0, email: null }); export class User extends userRecord implements IUser { id: number; gender: number; email: string; constructor(config: IUser) { super(config); } } immutable-records.ts
  • 96. Recap
  • 97. Async services Business facade Business logicCommunication logic Immutable app state Component tree root cmp sign-up form user UserModel User Action Creator signup(data) signup(data) RESTful Async Service process(action) userReducer register() RESTful CommandBuilder build(action) Restful Command Restful Gateway invoke() send() creates() uses as user$ uses user$ Stream Dependency Action (manipulation/method call) User registration user.email = email user.name = name
  • 98. Async services Business facade Business logicCommunication logic Immutable app state Component tree root cmp sign-up form user UserModel User Action Creator signup(data) RESTful Async Service process(action) userReducer register() RESTful CommandBuilder build(action) Restful Command Restful Gateway invoke() send() creates() uses as user$ uses user$ Stream Dependency Action (manipulation/method call) User registration user.email = email user.name = name signup(data)
  • 99. Async services Business facade Business logicCommunication logic Immutable app state Component tree root cmp sign-up form user UserModel User Action Creator RESTful Async Service process(action) userReducer register() RESTful CommandBuilder build(action) Restful Command Restful Gateway invoke() send() creates() uses as user$ uses user$ Stream Dependency Action (manipulation/method call) User registration user.email = email user.name = name signup(data) signup(data)
  • 100. Async services Business facade Business logicCommunication logic Immutable app state Component tree root cmp sign-up form user UserModel User Action Creator RESTful Async Service process(action) userReducer register() RESTful CommandBuilder build(action) Restful Command Restful Gateway invoke() send() creates() uses as user$ uses user$ Stream Dependency Action (manipulation/method call) User registration user.email = email user.name = name signup(data) signup(data)
  • 101. Async services Business facade Business logicCommunication logic Immutable app state Component tree root cmp sign-up form user UserModel User Action Creator RESTful Async Service process(action) userReducer register() RESTful CommandBuilder build(action) Restful Command Restful Gateway invoke() send() creates() uses as user$ uses user$ Stream Dependency Action (manipulation/method call) User registration user.email = email user.name = name signup(data) signup(data)
  • 102. Async services Business facade Business logicCommunication logic Immutable app state Component tree root cmp sign-up form user UserModel User Action Creator RESTful Async Service process(action) userReducer register() RESTful CommandBuilder build(action) Restful Command Restful Gateway invoke() send() creates() uses as user$ uses user$ Stream Dependency Action (manipulation/method call) User registration user.email = email user.name = name signup(data) signup(data)
  • 103. Async services Business facade Business logicCommunication logic Immutable app state Component tree root cmp sign-up form user UserModel User Action Creator RESTful Async Service process(action) userReducer register() RESTful CommandBuilder build(action) Restful Command Restful Gateway invoke() send() creates() uses as user$ uses user$ Stream Dependency Action (manipulation/method call) User registration user.email = email user.name = name signup(data) signup(data)
  • 104. Async services Business facade Business logicCommunication logic Immutable app state Component tree root cmp sign-up form user UserModel User Action Creator RESTful Async Service process(action) userReducer register() RESTful CommandBuilder build(action) Restful Command Restful Gateway invoke() send() creates() uses as user$ uses user$ Stream Dependency Action (manipulation/method call) User registration user.email = email user.name = name signup(data) signup(data)
  • 105. Async services Business facade Business logicCommunication logic Immutable app state Component tree root cmp sign-up form user UserModel User Action Creator RESTful Async Service process(action) userReducer register() RESTful CommandBuilder build(action) Restful Command Restful Gateway invoke() send() creates() uses as user$ uses user$ Stream Dependency Action (manipulation/method call) User registration user.email = email user.name = name signup(data) signup(data)
  • 106. Async services Business facade Business logicCommunication logic Immutable app state Component tree root cmp sign-up form user UserModel User Action Creator signup(data) RESTful Async Service process(action) userReducer register() RESTful CommandBuilder build(action) Restful Command Restful Gateway invoke() send() creates() uses as user$ uses user$ Stream Dependency Action (manipulation/method call) User registration user.email = email user.name = name signup(data)
  • 107. Properties… • Predictable state management • Testable (easy to mock services thanks to DI) • Not coupled to any remote service • Not coupled to any message format • Model can use different services based on context • Easy management of async events
  • 108. Properties… • Predictable state management • Testable (easy to mock services thanks to DI) • Not coupled to any remote service • Not coupled to any message format • Model can use different services based on context • Easy management of async events
  • 109. Properties… • Predictable state management • Testable (easy to mock services thanks to DI) • Not coupled to any remote service • Not coupled to any message format • Model can use different services based on context • Easy management of async events
  • 110. Properties… • Predictable state management • Testable (easy to mock services thanks to DI) • Not coupled to any remote service • Not coupled to any message format • Model can use different services based on context • Easy management of async events
  • 111. Properties… • Predictable state management • Testable (easy to mock services thanks to DI) • Not coupled to any remote service • Not coupled to any message format • Model can use different services based on context • Easy management of async events
  • 112. Properties… • Predictable state management • Testable (easy to mock services thanks to DI) • Not coupled to any remote service • Not coupled to any message format • Model can use different services based on context • Easy management of async events
  • 113. Properties… • Predictable state management • Testable (easy to mock services thanks to DI) • Not coupled to any remote service • Not coupled to any message format • Model can use different services based on context • Easy management of async events
  • 114. Resources • redux • ngrx • Scalable Single-Page Application Architecture • Demo