Meteor

advertisement
ISOMORPHIC REALTIME
APPS WITH METE R
Facebook-quality apps without Facebook’s money
Stephan Hochhaus
http://de.slideshare.net/stephanhochhaus/
meteor-not-just-for-rockstars
Laure Philips
The road so far
s
t
n
e
m
u
c
o
D
c
i
t
a
St
Static Clie
nts
HTML age
1990
2000
HTML, CSS, JavaScript
PhP / Perl / Java / …
Client
Server
JavaScript Libraries
MySql
Database
LAMP age
2000
2010
e
c
a
f
r
e
t
n
I
r
e
s
U
Client =
3 Tier Mo
del
LAMP age
2000
2010
One Page Apps
t
n
e
i
l
C
Rich
Offline Clien
t Storage
JavaScript age
2010
…
JavaScript conquered the server
Job Profile
Node Infographic
January 2015
Smaller Technology Stack
HTML, CSS, JavaScript
Client
Align Technology
PhP / Perl / Java / …
Server
Align Technology
JavaScript Libraries
MySql
Align Technology
Align Technology
Database
Smaller Technology Stack
HTML, CSS, JavaScript
JavaScript
Client
Server
JavaScript Libraries
NoSql
Database
T
“
ierless (also called single-tier, multi-tier or
isomorphic) programming enables developing a web
application as a single mono-linguistic application, which
renders its development akin to that of a desktop
application. ”
Opa
Links
Hop
Ur/Web
GWT
Mete
r
JavaScript era Meteor Framework
2010
2011
Meteor 1.0
2014
The Meteor Stack
Meteor
Node.js
Meteor Packages
MongoDB
Why is it so easy to learn?
$
curl https://install.meteor.com/ | sh
$
$
cd leaderboard
meteor
=> started your app
=> app running at http://localhost:3000
Why is it so easy to learn?
1
Tierless (Isomorphism)
2
Synchronicity
3
Reactivity
4
Smart Clients
1
Tierless Code
1
2
3
4
5
6
7
8
9
10
12
13
14
15
16
17
18
20
21
if (Meteor.isClient) {
Template.player.events({
'click': function () {
// Event handler
}
});
}
CLIENT
SERVER
if (Meteor.isServer) {
Meteor.startup(function () {
var names = ["Ada Lovelace", "Grace Hopper", "Marie Curie"];
_.each(names, function (name) {
Players.insert({
name: name,
score: Math.floor(Random.fraction() * 10) * 5
});
});
});
}
leaderboard.js
Accessing Data throughout
the Stack
1 var name = response.name
1 GET
2 http://server/users/
3
name/12345
1 SELECT name
2 FROM users
3 WHERE id = 12345
1
Clien
Server
Databa
Accessing Data throughout
the Stack
1 var name = response.name
1 GET
2 http://server/users/
3
name/12345
1 SELECT name
2 FROM users
3 WHERE id = 12345
1 Users.find(
2
{_id : 12345},
3
{fields :
4
{name : 1}})
1 Users.find(
2
{_id : 12345},
3
{fields :
4
{name : 1}})
1 Users.find(
2
{_id : 12345},
3
{fields :
4
{name : 1}})
1
Clien
Server
Databa
Accessing Data throughout
the Stack
1
2
3
4
5
6
7
8
9
10
11
12
13
14
var Players = new Mongo.Collection("players");
if (Meteor.isClient) {
Players.find({}, { sort: { score: -1, name: 1 } });
}
if (Meteor.isServer) {
Meteor.startup(function () {
Players.insert({
name: "Laure Philips",
score: Math.floor(Random.fraction() * 10) * 5
});
});
}
1
1
Mini Databases
create
read
update
delete
Offline Storage
Higher Availability
mini-MongoDB API
MongoDb API
MongoDb
Client
Server
Database
2
Event-Based Applications
Need Callbacks
Event
Event
Event
single-threaded
event handling
split off to
child process
Event
…
event loop
Disk
Network
Process
callback
…
2
Callback Hell
1 users.findOne({userId: 12345}, function (err, user) {
2
var logIn = {userName : user.name, when: new Date};
3
logins.insert(login, function (err, done) {
4
console.log(‘Login saved’);
5
})
6 })
2
Synchronicity with Meteor
1
2
3
4
var user = Meteor.users.findOne({userId: 12345};
var logIn = {userName : user.name, when: new Date};
logins.insert(login);
console.log(‘Login saved’);
2
The power of Fibers
wait
Fiber #1
(one per client
by default)
0
10
(idle cpu time)
20
30
40 ms
DB.connect
Connection.query
ExternalApi.makeCall
Connection.save
Request.send
Reactivity : no more
event-spaghettis
3
3
Traditional Programming
1
2
3
4
5
var a = 2
var b = 5
var c = a + b
console.log(c)
// c is 7
1 a = 5
2 console.log(c)
3 // c is still 7
1 c = a + b
2 // c is finally 10
3
Traditional Programming
1
2
3
4
5
var a = 2
var b = 5
var c = a + b
console.log(c)
// c is 7
1 a = 5
2 console.log(c)
3 // c is still 7
1 c = a + b
2 // c is finally 10
Reactive Programming
1
2
3
4
5
var a = 2
var b = 5
var c = a + b
console.log(c)
// c is 7
3
Traditional Programming
1
2
3
4
5
var a = 2
var b = 5
var c = a + b
console.log(c)
// c is 7
1 a = 5
2 console.log(c)
3 // c is still 7
1 c = a + b
2 // c is finally 10
Reactive Programming
1
2
3
4
5
var a = 2
var b = 5
var c = a + b
console.log(c)
// c is 7
1 a = 5
2 console.log(c)
3 // c is automagically 10
Reactive Programming in
Meteor
1
2
3
4
5
6
7
8
9
10
11
12
13
Session.set("a", 2);
Session.set("b", 5);
Tracker.autorun(function () {
var a = Session.get("a");
var b = Session.get("b");
Session.set("c", a + b);
console.log(Session.get("c"))
// c is 7
});
Session.set("a", 5);
// c is 10
3
Reactive Programming in
Meteor
Reactive data sources
Session variables
Collection.findOne && Collection.find
Meteor.user()
Reactive computations
Tracker.autorun
Templates
3
3
Meteor Templates
L
M
T
H
f
o
e
c
ie
p
a
is
te
la
p
m
A te
ta
a
d
ic
m
a
n
y
d
in
ta
n
o
c
n
a
c
t
tha
1
2
3
4
5
6
7
8
9
10
11
12
13
<head>
<title>Demo</title>
</head>
<body>
<h1>Welcome to Meteor!</h1>
{{> hello}}
</body>
<template name="hello">
<button>Click Me</button>
<p>You've pressed the button {{counter}} times.</p>
</template>
3
Meteor Templates
L
M
T
H
f
o
e
c
ie
p
a
is
te
la
p
m
A te
ta
a
d
ic
m
a
n
y
d
in
ta
n
o
c
n
a
c
t
tha
1
2
3
4
5
6
7
8
9
10
11
12
13
<head>
1 Session.setDefault('counter', 0);
<title>Demo</title>2 Template.hello.helpers({
</head>
3
counter: function () {
4
return Session.get('counter');
<body>
5
}
<h1>Welcome to Meteor!</h1>
6
});
{{> hello}}
7 });
</body>
<template name="hello">
<button>Click Me</button>
<p>You've pressed the button {{counter}} times.</p>
</template>
4
Smart Clients
Distributed Data Protocol
Client
RPC
HTTP
Server
JSON
4
Smart Clients
Distributed Data Protocol
Client
1 Meteor.call('hello', ‘jsconf.be',
2 function (err, res) {
3
console.log(res);
4 })
RPC
HTTP
Server
JSON
4
Smart Clients
Distributed Data Protocol
Client
1 Meteor.call('hello', ‘jsconf.be',
2 function (err, res) {
3
console.log(res);
4 })
RPC
HTTP
Server
JSON
1 Meteor.methods({
2
'hello' : function (name) {
3
return 'hello' + name;
4
}
5 })
4
Smart Clients
Triggers reactive updates
Client
App
App
Template
Template
DB
DB
Tracker
Server
Tracker
Pushes changes
App
DB
LiveQuery
Meteor Packages
Native
autopublish
session
template
accounts
Community
Meteor: some pitfalls
1
2
3
4
5
6
7
8
9
10
11
12
13
14
var car = {
name : 'Tesla model S',
color : 'white'
};
Session.set('favoriteCar', car);
Tracker.autorun(function () {
var favcar = Session.get('favoriteCar');
console.log('Your favorite car is ' + favcar.name)
});
car.color = 'red';
car.name = 'Ferrari F80';
Meteor: some pitfalls
1 Players = new Mongo.Collection("players");
2
3 if (Meteor.isClient) {
4
5
Tracker.autorun( {
6
var players = Players.find();
7
/* Which player was removed / updated / added ? */
8
});
9 }
Meteor: some pitfalls
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var slides = new Mongo.Collection('slides');
if (Meteor.isClient) {
/* Runs every time slide is changed */
Tracker.autorun( function () {
var slide = slides.findOne({});
Reveal.slide(slide.current_slide)
})
/* Runs every time user logs in / out */
Tracker.autorun( function () {
if (Meteor.user())
Reveal.configure({controls: true})
})
}
if (Meteor.isServer) {
Accounts.createUser({email:'jsconf@be', password: 'demo'})
}
Meteor: some pitfalls
1 var slides = new Mongo.Collection('slides');
2
s
y
e
k
I
P
A
in
a
rt
e
c
e
k
li
n
o
ti
a
rm
fo
in
e
iv
it
s
n
e
s
t
a
th
t
n
a
3
if
(Meteor.isClient)
{
rt
o
“ It’s imp
ly
n
o
re
rv
e
s
a
in
r
(o
k
c
lo
b
4
/* Runshin
every
time
slide
is
changed
*/
r
e
rv
e
S
is
r.
o
te
e
M
a
it
w
d
e
s
u
only b5e Tracker.autorun( function () {
e
th
ll
a
r
fo
le
ib
is
v
e
b
l
il
w
s
y
e
k
r
u
o
y
e
is
rw
e
th
o
r,
o
te
e
6
var
slide
=
slides.findOne({});
M
in
file)
7
Reveal.slide(slide.current_slide)
world to see. “
8
})
9
/* Runs every time user logs in / out */
s
e
g
a
k
c
a
p
d
n
a
r
10
Tracker.autorun(
function
()
{
o
te
e
M
n
o
l
a
< Tutori
11
if (Meteor.user())
12
Reveal.configure({controls: true})
13
})
14 }
15
16 if (Meteor.isServer) {
17
Accounts.createUser({email:'jsconf@be', password: 'demo'})
18 }
Meteor: some pitfalls
1
2
3
4
5
6
7
8
9
10
11
Template.hello.helpers({
counter : function () {
return Session.get('counter');
}
});
Template.hello.events({
'click button' : function () {
Session.set('counter', Session.get(‘counter') + random());
}
});
App
DB
App
DB
counter = 42
counter = 101
App
DB
Last Writer Wins
Ghent
Brussels
Antwerp
4 295
tweets
38 700
followers
11 172 questions
tagged meteor
Ghent
Brussels
Antwerp
4 295
tweets
38 700
followers
11 172 questions
tagged meteor
Demo time
Code can be found at
https://github.com/lphilips/meteordemo
Download