REALTIME WEB WITH
METEOR
Marc Rovira
36 years old, from Vic (Catalonia, Spain)
Multimedia Engineer
Project Manage | Agile Lead | Hybrid Mobile App Dev @ Medialab Barcelona
Professor @ La Salle University Barcelona Campus
core experiment
-
Open the same folder in two
different windows on your computer.
- Now click inside one of the two windows and delete a file.
a meteor is approaching...
...the atmosphere
...and here is the meteorite!
why the invasion?
WE'VE GOT THE POWER...
-
We have more powerful browsers
-
We have more bandwidth
-
We want to see real time information
-
We want to collaborate more often, want to be more social
-
We want to work offline
WELL WE HAVE RAILS!?
Yes, we do. Plus many other really good frameworks.
There is no silver bullet for constraints like:
MVC
RESTful CRUD actions
Traditional server side DB
WHAT WE NEED
Something that
-
Uses the resourcefulness of the modern computer/tablet/phone/TV
-
Has offline support
-
Responds instantaneously to data without needing AJAX or REST end points
Quick intro into evolution of JS development
current stack
EVOLUTION OF JS-DEVELOPMENT
-
1994 -
Netscape Enterprise Server (SSJS)
-
1995 -
Mocha
,
Livescript
was born
-
1996 - first standard:
ECMAScript
- 2008 - Google V8 JavaScript Engine was born
-
2009 - back on the server: node.js
-
2009 -
CommonJS
: Standard library
-
2011 -
Meteor.js
hit the earth
WHY SHOULD WE CARE?
-
The web becomes the platform of choice
-
This also includes the mobile market!
-
Transition:
- Static web sites -> interactive web apps
-
More requests -> scalability matters
-
The browser as the ecosystem
A small step for developers: node.js
A SMALL STEP: NODE.JS
-
One language (JS) to rule them all...
-
Scalable & fast
- Built-in HTTP server library
-
Active & engaged community (creating NPMs)
-
Fast-paced development
A FEW NUMBERS
-
PHP:
- 430 requests / second
- 99% requests were served in < 0.114s
-
Node:
- 3100 requests / second
- 99% request were served in < 0.047s
THE DARK SIDE
BOILERWHAT?
WHY, OH WHY?
A giant leap for developers: meteor.js
HIT IT, METEOR
WAIT WHAT?
BATTERIES INCLUDED
-
Templating engine
-
MongoDB
-
Live-updating for template
-
Latency compensation
-
Real-time-ish
-
User login via OAuth or your way
-
Can be indexed by Google
-
Package system (nodejs compatible)
-
Cloud platform
- and more...
so, what is
meteor?
Meteor is for NodeJS
whereas
Rails is for Ruby
A
+ OTHER optional JS LIBS
PACKAGED INTO ONE POWERFUL PLATFORM!
SOME FACTS ABOUT METEOR
- 01.12.11 - First preview release of "Skybreak"
-
25.07.12 - Received an $11.2 million round of financing
-
24.09.12 - Meteor 0.4.1: Sending email and Node 0.8
-
02.10.12 - Meteor 0.4.2: iOS 6 compatibility
-
17.10.12 - Meteor 0.5.0: authentication, user accounts, new screencast
-
20.11.12 - Meteor 0.5.1: database scaling
-
07.01.13 - Meteor 0.5.3: deployment settings, Minimongo, Spark, Accounts
-
13.02.13 - Meteor 0.5.5: Devshop code and community contributions
-
21.02.13 - Meteor 0.5.7: major scaling update, new DDP version, EJSON
-
13.03.13 - Meteor 0.5.8: security fix, AppCache, DB transforms, new Deps
-
04.04.13 - Meteor 0.6.0: brand new distribution system, app packages, NPM integration
-
16.04.13 - Meteor 0.6.2: D3.js v3, debugging improvements, experimental server-to-server DDP
-
15.05.13 - Meteor 0.6.3: WebSockets, MongoDB 2.4, Coffee 1.6.2, synthetic tap events
-
10.06.13 - Meteor 0.6.4: new OAuth packages and recommended updates
-
14.08.13 - Meteor 0.6.5: namespacing, modularity, new build system, source maps!
-
10.10.13 - Meteor 0.6.6: content security policy, upsert and $near, Node 0.10
-
17.12.13 - Meteor 0.7.0: Scalable database queries using MongoDB oplog instead of poll-and-diff
-
24.02.14 - Meteor 0.7.1: oplog support for complex queries, Meteor developer accounts
-
18.03.14 - Meteor 0.7.2: completing our work scaling realtime MongoDB queries
- Early 2014 - Expected Meteor 1.0
support
YOU SHOULD USE IT.
Your customer should not. Well, not yet at least.
Meteor is currently at v0.7.2, which means:
-
It isn't ready for primetime.
-
Give it some time, try it, improve it!
Their guess: More than a month, less than a year. There are several (eleven?) people working full time on it. Meteor is definitely going to mature faster than any framework you could afford to build in-house, unless you're Google or Facebook.
who is behind meteor?
awesome team!
Geoff Schmidt — @immir |
Matt DeBergalis — @debergalis |
Nick Martin — @n1mmy |
David Greenspan — @DavidLG |
Avital Oliver |
David Glasser — @glasser |
Jade Wang — @qiqing |
Kara Yu — @kara_yu |
Alice Yu — @yaliceme |
Slava Kim — @imslavko |
Emily Stark — @estark37 |
how meteor works
traditional web apps
source: discovermeteor.com
single-page web apps
source: discovermeteor.com
real-time, single-page apps
what is different?
METEOR AS A SERVER AND A CLIENT
Meteor as a Server and a Client
Meteor allows developers to build applications without worrying about the complexities of client-server connectivity.
source: meteorhacks.com
THREE DIFFERENT TYPES OF REQUESTS
- Static Files
- DDP Messages
-
HTTP Requests
static files
ddp messages
DDP (Distributed Data Protocol) is the protocol Meteor uses to communicate between client and server. All client-side subscription data, method calls and MongoDB operations are communicated as DDP messages. This is a very lightweight protocol. These messages can be inspected with a handy tool called ddp-analyzer.
http requests
While there is no official documentation, Meteor can handle HTTP Requests similar to other traditional applications. For example, file uploads to a Meteor app are sent as HTTP Requests.
Two Types of Servers
Although Meteor runs on a single port, internally it works as two separate servers:
source: meteorhacks.com
HTTP Server
The HTTP server is used to serve static files and HTTP requests. Meteor uses the connect Node.js module for this purpose.
DDP Server
The DDP server handles all publications, MongoDB operations, RPC and Meteor methods. Easy to read, it uses EJSON.
Meteor uses SockJS as the transport protocol. Nowadays, the DDP server is a SockJS server customized for Meteor.
how meteor works
cool features
Integrated framework
PURE JS
Write your entire app in pure JavaScript. All the same APIs are available on the client and the server — including database APIs! — so the same code can easily run in either environment.
automatic includes
Don’t specify CSS, JS, or even HTML files to be included on any page. They are all just combined together, which sounds a little odd, but it makes things even quicker and easier to develop.
Minification and concatenation in production
Meteor minifies and concatenates all JavaScript (including templates, which are pre-compiled as JavaScript) and CSS files for you in production, and serves them as static files—and not minified or combined in dev, for easier debugging.
Instant user account support
Setting up user accounts is super easy, you can add support for a variety of common user account systems and there’s even a default login widget that you can reuse.
The interface itself even lets you seamlessly setup the app tokens for twitter, facebook, or other oauth services.
sending e-mails
Email.send({
from: from,
to: to,
subject: subject,
text: text
});
on the server.
LIVE PAGE UPDATES
Just write your templates. They automatically update when data in the database changes. No more boilerplate redraw code to write. Supports any templating language.
CLEAN, POWERFUL DATA SYNCHRONISATION
Write your client code as if it were running
on the server and had direct access to the database.
No more loading your data from REST endpoints.
INTEROPERABILITY
You can connect anything to Meteor, from native mobile apps to legacy databases to Arduinos.
Just implement the simple Distributed Data Protocol (DDP).
LATENCY COMPENSATION
When a user makes a change, their screen updates immediately — no waiting for the server.
If the server rejects their request or executes it differently, the client is patched up with what actually happened.
HOT CODE PUSHES/reload
Whenever you save changes in your project,
any web pages that are viewing your app
will automatically refresh.
(no more hitting refresh button in your browser after making changes)
When you push a new version, the new code
is seamlessly injected into each browser frame
in which the app is open.
Continuous Delivery Vn+1
FULLY SELF-CONTAINED APPLICATION BUNDLES
One command to compile your entire application into a tarball.
Unpack it anywhere there's node.js, MongoDB and handlebars installed, run one command, and you're on the air.
You're never locked into a particular hosting provider; you have all the code for the platform.
SMART PACKAGES
+ any NPM package too
Meteor's Smart Packages are actually little programs that can inject code into the client or the server, or even hook into the bundler to preprocess your source.
Great care has been taken to give the core Meteor packages the minimal set of dependencies, so you can use your favorite templating, testing, or DOM manipulation frameworks.
Is Meteor MVC?
and much more...
Works offline - Persists the changes once network is restored
Built in Redundancy - Works on all popular browsers
and IE 7 +
Community - Incredible community already forming
Open Source - Open source, extremely well funded
https://github.com/meteor/meteor/tree/master
https://trello.com/b/hjBDflxp/meteor-roadmap
Meteor is not only for experts - Suitable for web beginners
The Perfect Match For Lean Startups - Certainly for rapid prototyping or building MVPs
7
principles
1.
data
on
wire
2.
one
language
3.
database
everywhere
4.
latency
compensation
5.
full
stack
reactivity
6.
embrace
the
ecosystem
7.
Simplicity
equals
productivity
Hands-on time
tools
$ parts install meteor
students practice
REQUIREMENTS
-
Folder Structure
- Reactive Data Sources:
- Session variables
-
Synchronized Collections (restricting r/w access)
- $ meteor remove autopublish insecure
-
Deployment on Meteor infrastructure
- Minimum add 3 Packages from:
- Local, NPM packages, Meteor Smart Packages
- Atmosphere Smart Packages (iron-router recommended)
STUDENTS PRACTICE
more REQUIREMENTS
- User accounts
- Recommended to use some front-end framework (ex. bootstrap-3, bootflat, foundation-5, gumby2, jqueryui, metroui...)
- Optional section to improve mark:
- Built a Smart Package and upload it to Atmosphere
- Push source code to GitHub repository:
- https://github.com/SalleMeteor/<app_name>.git
- Edit "README.md" file and add the following info:
- App name, App description, members, list of packages to install manually, deployed URL, and more?
STUDENTS PRACTICE
IMPORTANT DATES
- 24/03 - 28/03 > E-mail me with your App details:
- Team members (names, emails, GitHub user accounts)
- App name and short description
- 22/04 > Practice delivery (last git push)
- 23/04 - End of April > Group interviews
basic git commands
$ meteor create <app_name>
$ cd <app_name>
$ git init
$ git remote add <short_name> https://github.com/SalleMeteor/<app_name>.git
$ git remote -v
$ git pull <short_name> master
$ git add -A
BASIC GIT COMMANDS
$ git commit -m "<message_to_record>"
$ git push <short_name> master
$ git status
$ git clone <git_repository_URL>
learn git
Quickstart
$ curl https://install.meteor.com | /bin/sh
$ meteor create myapp
$ cd myapp
$ meteor
=> Meteor server running on: http://localhost:3000/
$ meteor create --example leaderboard
$ meteor create --example parties
$ meteor create --example todos
$ meteor create --example wordplay
meteor internals
packages & cli
Command Line Tool
$ meteor create myapp
$ meteor reset
$ meteor update
$ meteor help
...
Packages
Command Line Tool
Meteor's Command line tool is similar to rake (ruby) or jake (nodejs). This does all the background work of collecting, reading, compiling (pre-processing coffee/scss/less files) and minifying.
The command line tool also lets you perform app specific actions like interacting with your database, deploying/bundling you app, viewing logs, adding/removing packages, etc.
packages
Packages are modules (or chunks) of pre-written code that you can use in your applications. There are 5 types of packages:
-
Core Packages - These packages are used in almost every meteor app, and you will pretty much never need to worry about these
-
Meteor Smart Packages - Optional Packages that come bundled with Meteor and you can use for performing specific actions
-
Atmosphere Smart Packages - 3rd party (community-written packages that can be install via meteorite.
-
NPM packages - Does not work out of the box but can be used
-
Local packages - Files that you put into /packages folder inside your Meteor app
Using Meteor Smart Packages
Small JavaScript programs that can inject code into the client or the server.
Can be used to add functionality to app (send emails, add user accounts) or extend the build process (precompile coffeescript or less files).
Examples: jQuery, Underscore, Backbone, Bootstrap, Accounts, Email...$ meteor list $ meteor list --using $ meteor add <package_name> $ meteor remove <package_name>
...
Structure,
Architecture
&
load order
Application Structure
You can write an entire app in just one file, but it's not recommended.
Meteor provides you an efficient way to structure and organize your files. There are no script tags, no loader libraries and no dependency management.
Just put files in appropriate folders and Meteor will pick it up automatically.
Separating Client/Server Code
Meteor provides us with isClient and isServer checks to separate out what part of the code needs to be executed on the server and what needs to be executed inside the browser.
if (Meteor.isClient) {
someFunction = function() {
// your code goes here
};
...
}
if (Meteor.isServer) {
Meteor.startup(function() {
// code to run on server at startup
});
...
}
Folder Structure
- /client - For code that only runs on the client. Meteor pre-
-
processes files in this folder and minifies it before rendering. Place for putting CSS/SCSS/Less files, and templates
-
/server - For code that only runs on the server. Keep your API keys and other private data files in this folder so that it is not accessible by users. (You can also use /private for this)
- /public - Place to store favicon.ico, robots.txt, sitemap.xml, images, etc. (CSS files are not considered static assets)
- /tests - For code that tests your App. Not loaded anywhere
- /packages - For any package that uses your app
- /.meteor - Hidden folder with Meteor internal files. Interesting files: "packages" and "release"
- /everywhere else - client & server
FILE/folder structure
$git clone https://github.com/SachaG/Void.git
load order
Meteor has a set of rules that dictate the order in which files are executed. Instead of using dependency management, you should organize your files according to these rules:
- Files in the /lib directory are loaded first
-
Files that match main.* are loaded last
-
Files in subdirectories are loaded before files in parent directories (deepest to shallowest)
- Within a directory, files are loaded in alphabetical order.
TEMPLATING
&
LIVE HTML
HTML and Templates
HTML files in a Meteor app are different from regular HTML files. There is no <!doctype>, no <script> tags and no css imports.
There are three root level tags:
<head></head>
<body></body>
<template></template>
templates
Templates are regular HTML expressions, but with the ability to embed expressions (variables, values of properties, etc.).
Today, the only templating system that has been packaged for Meteor is Handlebars.
Without Handlebars
$("div").text(name + "is " + age + " years old.");
With Handlebars
<div>{{ name }} is {{ age }} years old.</div>
Creating A Template
<body>
{{> hello}}
</body>
<template name="hello">
<h1>Hello World!</h1>
</template>
<template> is a root level tag that Meteor provides us to create templates. Template names should be unique.
expressions inside templates
-
Partials - Partials use the {{> template_name}} syntax. Meteor simply replaces the partial with the template of the same name.
-
Helpers - Helpers use the {{ title }} syntax. Meteor replaces this with the value of a property of the current object, or the return value of a template helper.
- Block Helpers - Block Helpers are conditional statements to control the flow of template.
Handlebars Block Helpers
{{#if currentUser }}
<p>Secret View</p>
{{else}}
<p>Access Denied</p>
{{/if}}
{{#unless newUser}}
<p>Welcome back</p>
{{else}}
<p>Good to have you here</p>
{{/unless}}
{{#each contacts}}
<p>Name: {{fullName}}</p>
{{/each}}
Inside the each block, the value of this is set to the currently iterated object. There is no need to call this.fullNamespecial block helpers
SPECIAL BLOCK HELPERS
Template Helper Functions
To interact with templates with javascript, Meteor converts all template sections into JavaScript functions that are accessible via a global Template namespace.
To provide data to templates, add functions on
Template.template_name
object.
In HTML file | In Javascript file |
---|---|
|
|
|
|
Template Events
To respond to user inputs, we need to listen for events like click, double click, keypress, etc. The event and the target element is specified as a string value by a space. This forms the key of the object. The callback function that gets executed when this event occurs is defined as the value.
Template.hello.events({
"click input": function(e, t) {
alert("You clicked the input.");
}
});
template callbacks
reactivity
Reactivity
Reactive Programming - results will be automatically recalculated whenever data associated with that piece of code changes.
-
Templates
-
Deps.autorun
- Meteor.render and Meteor.renderList
Reactive Data Sources (DS) - is any provider of data that follows Meteor’s contract for providing reactivity.
- Meteor.user, Meteor.userId, Meteor.loggingIn
- Meteor.status
- Session variables
- Database queries on Collections
Reactive context: deps.autorun
Deps.autorun(function () {
Meteor.subscribe("messages", Session.get("currentRoomId"));
});
// Causes the function passed to Deps.autorun to be re-run, so
// that the 'messages' subscription is moved to the room "home".
Session.set("currentRoomId", "home");
REACTIVE CONTEXT: Meteor.render
// Client side: show the number of players online.
var frag = Meteor.render(function () {
return "<p>There are " + Players.find({online: true}).count() +
" players online.</p>";
});
document.body.appendChild(frag);
// Server side: find all players that have been idle for a while,
// and mark them as offline. The count on the screen will
// automatically update on all clients.
Players.update({idleTime: {$gt: 30}}, {$set: {online: false}});
REACTIVE CONTEXT: METEOR.RENDERLIST
// List the titles of all of the posts that have the tag
// "frontpage". Keep the list updated as new posts are made, as tags
// change, etc. Display the selected post differently.
var frag = Meteor.renderList(
Posts.find({tags: "frontpage"}),
function(post) {
var style = Session.equals("selectedId", post._id) ? "selected" : "";
// A real app would need to quote/sanitize post.name
return '<div class="' + style + '">' + post.name + '</div>';
});
document.body.appendChild(frag);
// Select a post. This will cause only the selected item and the
// previously selected item to update.
var somePost = Posts.findOne({tags: "frontpage"});
Session.set("selectedId", somePost._id);
REACTIVE ds: meteor.user()
REACTIVE DS: Meteor.userId()
REACTIVE DS: METEOR.loggingIn()
REACTIVE DS: Meteor.status()
Deps.autorun(function () {
if (Meteor.status().connected) {
console.log("connected");
} else {
console.log("disconnected");
}
});
REACTIVE DS: Session Storage
Session.set("currentTask", "Learn Meteor");
Session.set("currentPage", "documentationPage");
...
Session.get("currentTask"); // output: "Learn Meteor"
Session.get("currentPage"); // output: "documentationPage"
...
Session.equals("currentTask", "Learn Meteor"); // output: true
Mongo DB
&
COLLECTIONS
Persistent Data Storage
collections
Synchronized Collections (anywhere):
Contacts = new Meteor.Collection("contacts");
Unsynchronized (local) Collections (client only):
Contacts = new Meteor.Collection(null);
on Client Side
Working With Collections
Contacts.insert({ name: "Marc" });
Contacts.find();
Contacts.find({ name: "Marc" });
Contacts.findOne({ name: "Marc" });
Contacts.update({ name: "Marc" }, { $set: { name: "Joan" }});
Contacts.remove({ name: "Marc" });
Reset Database from CLI$ meteor reset
Accounts,
SECURITY & input validation
Accounts
accounts-base, accounts-password, accounts-facebook, accounts-github, accounts-google, accounts-meetup, accounts-twitter, accounts-weibo, etc.
accounts-ui
ACCOUNTS
$ meteor add accounts-base accounts-password accounts-ui
<template name="header">
{{loginButtons}}
</template>
{{#if currentUser}}
<h1>Logged in</h1>
{{/if}}
Meteor.user();
Meteor.userId();
Accounts.ui.config({
passwordSignupFields: 'USERNAME_ONLY'
});
Security
Restricting Read Access - Publish/Subscribe
$ meteor remove autopublish
$ meteor remove insecure
Publish/Subscribe
Meteor.publish("myContacts", function(name) { //return Contacts.find(); // to get all contacts
return Contacts.find({ username: name }); });
Meteor.subscribe("myContacts", "cramrov");
Restricting Write Access - Allow/Deny
Contacts.allow({ insert: function(userId, doc) { return !!userId }, update: function(userId, doc) { if(userId && doc.userId == userId) return true; return false; }, remove: function(userId, doc) { if(userId && doc.userId == userId) return true; return false; } });
Contacts.deny({ remove: function (userId, doc) { //can't remove locked contacts return doc.locked; } });
Restricting Write Access - Methods
Meteor.methods({
foo: function (arg1, arg2) {
// .. do stuff ..
if (you want to throw an error)
throw new Meteor.Error(404, "Can't find my pants");
return "some return value";
},
bar: function () {
// .. do other stuff ..
return "baz";
}
});
// async call
Meteor.call('foo', 1, 2, function (error, result) { ... } );
// sync call
var result = Meteor.call('bar');
input validation
check(username, String);
Deployment
&
Packaging
Deployment
on Meteor infrastructure
$ meteor deploy myapp.meteor.com
$ meteor deploy www.myapp.com // CNAME pointing to origin.meteor.com
on own/third-party infrastructure
$ meteor bundle myapp.tgz
$ demeteorizer [options]
$ ./bundle-static.py
deployment in meteor 0.7.1+
- New login system to manage deployed apps
- Developer accounts replace the old site passwords on meteor deploy
- Use the accounts system to authorize other users to manage your apps
- You can add support in your app with meteor add accounts-meteor developer, and then adding {{loginButtons}} in your template
Ecosystem
METEORITE
"Meteorite is a Meteor version manager and package manager. It provides an easy way to run different versions of meteor, use non-core packages, and to install packages from the
Atmosphere ( atmosphere.meteor.com ) package repository."
Meteorite adds the mrt command.
$ npm install -g meteorite
OR
$ sudo -H npm install -g meteorite (if you need root permissions)
$ mrt create myapp
$ mrt add <package_name>
$ mrt remove <package_name>
$ mrt run --production
ATMOSPHERE
atmosphere v2
building a smart package
Who's using Meteor
experiments
experiments
Learn Meteor
RTFM!
...and the Meteor-Style-Guide too
discovermeteor.com/translations
Best Learning Resources for Meteor.js
FURTHER READING
looking for jobs?
Job boards for Meteor
conclusion
+ easy to start with
+ fast development
+ open platform
+ the (mobile) web is a big market
+ one language for front and back end
- still in rapid development / no stable release yet
- may be too high level for some (complex) cases
- still needs more packages -> Atmosphere
- scalability is important
Try it out and you will see its awesomeness!
Thanks for listening!
Questions?
marcr@salleurl.edumarcrvall@gmail.com
REALTIME WEB WITH METEOR
By Marc Rovira Vall
REALTIME WEB WITH METEOR
- 4,279