Last weekend I finally got around to building something with Meteor and what follows is a short description of my experience with the platform with a few take aways.
Installing Meteor is super straightforward
$ curl https://install.meteor.com/ | sh
Once you have Meteor, you'll want Meteorite as well. Meteor comes with a few official packages. Most 'unofficial' packages live in the Atmosphere. Meteorite helps you deal with those in a more streamlined way. You want streamlined, so grab Meteorite.
npm install -g meteorite
With Meteorite in place, the way to create a Meteor app is as follows
# Create an app based on Meteor's devel branch.
$ mrt create my-app --branch devel
$ cd my-app
# Install an Atmosphere package, recursively fetching dependencies.
$ mrt add router
# Check for and install any updates, and run the app.
$ mrt
Now, that gives you a basic boilerplate which is fine but you might want to explore different boilerplates which are slightly more structured. There a few out there. Sacha Greif has one which i copied quite a bit to roll my own. Having a boilerplate you are comfortable with is important and makes you more productive.
Learning while building is a lot of fun. My first Meteor application is called ONAIR. It lets you play your favorite tunes from Soundcloud and let your friends/strangers tune in and listen
Setting specific goals for your first application and then figuring out how to reach them using specific platform helps quite a bit. With ONAIR my goal where as follows:
- allow people to connect with their Soundlcoud and Facebook accounts
- import person's favorites from Soundcloud to the application
- have playlists that can be edited in realtime with changes propagating to all the listeners
- [not implemented yet] have multiple people DJ at the same time
- [not implemented yet] have listeners provide real time feedback on the sounds (e.g. cheers, thumbs up/down etc)
- have the app structured in a way that would make it scalable and maintainable
Meteor has really good support for OAuth. There are packages for Facebook, Twitter, Github, Google, Meetup and Weibo. There's a Soundlcoud OAuth package maintained by Sylvain Gizard here. Whatever you do, just make sure you get service configs right:
// in server/users.js
//setup login service config
Meteor.startup(function () {
Accounts.loginServiceConfiguration.remove({
service: "soundcloud"
});
Accounts.loginServiceConfiguration.insert({
service: "soundcloud",
clientId : Meteor.settings.soundcloud.clientId,
secret : Meteor.settings.soundcloud.secret
});
Accounts.loginServiceConfiguration.remove({
service: "facebook"
});
Accounts.loginServiceConfiguration.insert({
service: "facebook",
appId: Meteor.settings.facebook.appId,
secret: Meteor.settings.facebook.secret
});
});
I had to query Soundcloud's API to get person's favorite songs. My approach was to use Soundcloud's Javascript SDK on the client. Now, the SDK needs an access token obtained through the OAUTH call. Here's how I accomplished that
checkOAuth : function(){
var Soundcloud = this;
return Meteor.subscribe('SC.OAuth',function(){
//TODO: check for errors
var user = Meteor.user();
if(user){
if(user.services.soundcloud){
var accessToken = user.services.soundcloud.accessToken;
if(accessToken){
// SC is the variable exposed by the Soundcloud SDK
SC.accessToken(accessToken);
Soundcloud.getFavorites();
}
}
}
});
}
Here I am using Meteor's publish/subscribe mechanism to transfer data from the server to the client.
With access token in place, grabbing favorites is easy
getFavorites : function(){
SC.get("/me/favorites", function(response){
if(response.errors){
//TODO: do smth here
return;
}
Session.set('sc.favorites',response);
});
}
Using Meteor's session storage to keep favorites data.
With Meteor it's a given really. As long as you stick to using Meteors data layer, changes propagate to all clients (as long as clients subscribe to datasets using Meteor.subscribe). I do recommend turning autopublish ASAP so you get a real picture as to what is really going on with your data
By default, a new Meteor app includes the autopublish and insecure packages, which together mimic the effect of each client having full read/write access to the server's database. These are useful prototyping tools, but typically not appropriate for production applications. When you're ready, just remove the packages.
When you start going beyond hello world, you'll want some sensible way of structuring your Meteor application. Your application boilerplate should help you do that. A few choices I made early on
- clear client/server separation using directories (as opposed to using Meteor.isClient/Meteor.isSever)
- using IronRouter with class based controllers
- SASS + bourbon because you do not want to write css
- keep your application settings organized (i have 2 sets of settings that i load using --settings directive)
- take a look at Sacha Greif's Telescope to get an idea of what to expect from a larger Meteor app
All the code is on Github. I intend to have a couple other installments of these diaries as I continue working on this, so keep in touch. I'd love to hear about your experience with Meteor as well.
Thanks a lot for writing this up. I was struggling with 401 errors on authenticated requests. I hadn't see it documented anywhere that i needed to manually set the access token:
SC.accessToken(accessToken);
.Bit help, thanks again.