Hacker News new | past | comments | ask | show | jobs | submit login
Sails.js: Realtime MVC framework for Node.js (balderdashy.github.com)
186 points by iamwil on Mar 14, 2013 | hide | past | web | favorite | 98 comments

This looks incredibly cool, but if there is one thing that I've learned, it's that less magic is generally better when building a real production application (vs a weekend project). While typing something like 'sails generate model User' is nice, I literally have no idea what that just did. In the video it then shows a user creating new attributes on the model via a REST API - what??(he even mistakenly adds a bad attribute and then proceeds to just leave it there...).

After working with a few of these frameworks it always seems to lead to spaghetti code where the code I write weaves in and out of the framework at different pre-defined connection points (Sails calls them policies I think). I always take note of all the times the developer says 'automatically', these are all the places that will break when my requirements don't exactly match up with theirs.

  $ sails generate model User
  $ git diff

In my mind "I need to turn to my version control system to have a clue what just happened" is a great example of having too much magic for a production product.

It's a generator. It generates files. Typing it out would be less magical, but then it wouldn't be a generator. To me, git diff seems like a fine way to see what it did, tbh.

Couldn't agree more. On a different topic, I've been toying with various JS MVC frameworks, but a lot of them tries to do their "magic" without actually explaining why the magic is necessary. These so called "conventions" at times hide way too many things, it actually makes it frustrating to understand. In the end, my choice came back to Backbone, which is the minimalistic framework.

Having said that, I'm trying to pick up NodeJS soon, what frameworks would you recommend to start off with? Express?

Yes, express is very simple, and easy to learn and write. It's also the most popular web framework for node.js.

It's less like rails/django and more like sinatra/flask.

Hey guys, I wrote Sails.js. The controllers are just sets of Express middleware. The reason I did it this way is that I wanted a conventional abstraction (MVC) without the burden of a new API.

The only real "magic" here is how Sails handles Socket.io requests using the same controllers. Sails generates req/res objects for socket requests and allows you to handle WebSocket requests in the same code base as the rest of your app. If you need to do more custom stuff, you can still directly access Socket.io through sails.io, and each request object that came from a socket request contains req.socket, which gets you access to the socket which sent the message.

@sideproject Actually you can use Sails (https://github.com/balderdashy/sails) with whichever front-end framework you like. It's architected to serve a nice clean RESTful API and leave the front-end up to you.

The argument (as I see it) against choosing something like Backbone in order to avoid framework "conventions" is that you inevitably end up inventing your own conventions to fill in the gaps.

Fine if you're a one-man team (although still arguably only in the short-term), but if not, all you've done is shifted the "conventions" problem onto your co-workers, only now they have to learn yours, rather than the (hopefully) well documented and worked-out conventions of the framework you tried to avoid to begin with.

(I'm currently using Backbone by the way, but very conscious that it could be a short-sighted approach - basically I'm keeping a keen eye on Ember)!

Absolutely agree-- Backbone is a great step in the right direction, but it leaves tons of things to chance. We use Mast internally (https://github.com/balderdashy/mast) but I'm keeping a close eye on Ember and Angular. Also, if you're already doing Backbone, you might check out Marionette.

Yep. 'Leaving things to chance' is a good way to put it. Thanks, I'm aware of Marionette and have also used Backbone.LayoutManager [1] before which solves some of the same issues, though I am wary of the cobbled-together stack I might end-up with if I pick Backbone + Marionette + Some-Better-Router + ... That's certainly why Ember appeals, especially now they're beginning to nail the docs and there are great resources emerging like the recent Peepcode episode [2], which I'm going to have a watch a few more times through.

Very interesting work with Sails, as someone who's written (much more basic) REST scaffolding scripts before I'm especially intrigued by that angle. I'll be digging into it for sure.

[1] https://github.com/tbranyen/backbone.layoutmanager

[2] https://peepcode.com/products/emberjs

Mast looks cool! I'm going to check it out.


This looks great! The automatic API generation is a killer feature that makes me want to try this out sometime soon. Only thing that seems strange to me is adding the <resource>/create, <resource>/update, and <resource>/destroy GET endpoints -- why not keep it RESTful?

Hey Peter-- RESTful endpoints are supported. The other options are just there for convenience while testing. You can disable those routes later if you like in your routing table. Policy mapping happens at a controller level to solve this very problem and prevent devs from inadvertently granting access to a piece of code they didn't mean to.

# List of all users http://localhost:1337/user

# Find the user with id 1 http://localhost:1337/user/1

# Create a new user http://localhost:1337/user/create?name=Fisslewick (or send an HTTP POST to http://localhost:1337/user)

# Update the name of the user with id 1 http://localhost:1337/user/update/1?name=Gordo (or send an HTTP PUT to http://localhost:1337/user/1)

# Destroy the user with id 1 http://localhost:1337/user/destroy/1 (or send an HTTP DELETE to http://localhost:1337/user/1)

I saw that the RESTful endpoints also existed, I was just curious about the additional ones. Knowing that I can easily choose to disable them is great to know — maybe mention it in the docs? I think that exposing these routes for testing is a great idea, but depending on them in production would be rather terrible and dangerous.

how would you delete the incorrectly created key from the video?

nice work btw, the end to end of it is attractive if somewhat magical.

I can see the desire to be able to execute non-GET commands via the browser's address bar. Another way Sails could accomplish that would be to accept "?method=PUT|POST|DELETE" to mimic the desired HTTP method.

I don't think that solves the underlying problem of side effect-ful/dangerous GET requests that may be easily exploited via CSRF attacks. You really don't want to expose POST/PUT/DELETE actions via GET.

Avoiding GET requests is not a fool proof way to mitigate CSRF. If your website has just one XSS vulnerability an attacker can send POST requests. It's much better to use some kind of token that is always sent with your forms.

And if you have zero XSS vulnerabilities, they may be able to trick users into interacting with a form on a site they control (the "CS" of "CSRF"). CSRF token is definitely necessary.

Reference: https://www.owasp.org/index.php/Top_10_2013-A8-Cross-Site_Re...

There's nothing stopping anyone from sending POST requests to wherever he wants, even without an XSS. the same-domain origin policy only forbids you from reading the response, not from sending the request. CSRF-wise, POST requests are just as vulnerable as GET requests.

Also, if someone does manage to find an XSS vulnerability, using a CSRF token won't be any good - the attacker can simply read the token from your website and use it.

No. Before performing a POST/PUT/DELETE or any other method with side effect to another domain your brother will issue an OPTIONS to get authorization first and will never perform the request if the server do not authorize it.

Then if your authentication is cookie based and you allow to delete resource via GET then all the attacker have to do is to insert <script> or <img> tag on any other domain with the proper src attribute to delete your content silently.

These endpoints are a VERY bad idea and are absolutly not REST. RESTful do not mean CRUD.

`<form>`s are allowed to send POST requests to wherever they want, without any restrictions. By creating a form that points to another domain, and automatically submitting it, you can send a POST request to wherever you want [1].

POST requests can be easily sent cross-domain. NO ONE SHOULD EVER think that just because he's not using GET requests he's safe from CSRF attacks.

[1] See http://jsfiddle.net/8xnB3/5/ for example (which sent this comment).

EDIT: Just to clarify - I'm not saying that exposing those endspoints via GET is a good idea, I think its horrible. But people should be aware that avoiding GET does not protect against CSRF, and you still have to use CSRF tokens.

Hi nadaviv, if you don't want to expose those endpoints via GET, you don't have to. Those are set up that way in development so it's much easier to get started. You have full control over your routing table and access control policies.

How common are CSRF attacks? My sites are not protected at all but I don't know if it's worth the hassle to fix. It just doesn't seem like a big deal and very unlikely to happen.

> I can see the desire to be able to execute non-GET commands via the browser's address bar.

I can certainly see the desire for that as a browser feature; using GET for actions that are neither safe (no impact other than retrieval) nor idempotent is probably not a good way to workaround the lack of such a browser feature, since per the HTTP/1.1 spec, GET should be safe and is defined as idempotent. (See Secs. 9.1.1 and 9.1.2 of RFC 2616.)

I'll rephrase something I read this morning on SO about the difference between GET and POST:

"GET request are not supposed to imply any modification on the serveur."

Remember C++ constness?

According to HTTP - GET request should be idempotent. Even if you mimic the other verbs using query string, it is still a GET request.

Maintainer seems to be aware of the need to keep a conventional RESTful approach. The default state for `routes.js` includes a commented section about setting up HTTP verb routing.

It does look exciting, but I can't trust a framework that promotes saving data on a GET request.

Definitely not promoting it! That's a convenience feature to make it easy to see what's happening during development. You can disable that behavior in your routing table.

If it's on the homepage and in the docs, people will copy it without questioning it. That's why people use frameworks.

Not you though, sounds like!

Sarcasm, nice.

But seriously, I'm new to Node. If I see examples of bad practice on the home page, I've no way of knowing if the framework is going to be teaching me more bad practices in the areas I'm not familiar with yet.

I really hope you start using a framework. This would free up more time for you to develop a sense of humor! :)

A sense of humour normally gets you downvotes on here :-p

Why not?

Because GET requests can be saved as bookmarks, copied and pasted, indexed by search engines, etc.

By the way, I forgot to mention this before, but you can quickly disable this behavior in polices.js or routes.js config file when you're ready to switch to production. In 0.9, you'll be able to generate controllers with this feature disabled from the CLI as well.

If you're looking for a super simple solution, check out Sajak https://github.com/jed/sajak. It's great for making a basic JSON API.

I wish more people would read this blog post before writing another MVC framework in Node.


It looks like Sail.js is a pretty good response to that blog post. It doesn't go all the way of his dream framework, but it also isn't just another straight "Sinatra/Django/Rails" clone.

Except without leveraging those V8 features, we don't have what makes node.

The pace of invention today is based on iteration, building upon other successes and similar ideas - and its happening in real-time across a vast community. This is awesome.

Personally, I love that we have choices like derby, meteor and potentially, sail. Every effort has pro's / con's that may or may not be ideal for a particular use case. I would rather have more options than none.

I think my issues with this are that it's cool, but there's no example of security, and the tests are pretty much missing... I tend to look for either tests, or samples for how things get done, and without any security/authentication bits, I don't know what I would use something like this for.

TFA says "You know what would be awesome? If we wrote our libraries so that they could run either on the server or on the client, and they did so in a transparent way."

Ever tried GWT? I played with it a bit. It gives you One Language -- Java -- and does a pretty good job of it. It comes the closest to accomplishing what the author is talking about.

Unfortunately it puts this huge condom between you and the web medium itself, making design nuance difficult to achieve. But if I had to write, say, an accounting app for a car rental agency I would seriously look at it. It would be a great way to create a solid, stable web thin client app.

Judging from the description it does what the other 1000+ Node MVC frameworks do. What's the advantage of Sails over them? CRUD scaffolding is nothing new in Node's ecosystem.

Apparently their edge is that users can manipulate the database on their own in the default scaffold?

EDIT: Downvote without a comment is not constructive. This is a legitimate question. Care to explain?

I agree with you, seems that there are a million different frameworks but not enough community around one to make any of them really stick. If all the devs for those different projects could just put their heads together into one project...

It looks a lot like TowerJS or CompoundJS or FlatIron, but I'm still going to try it because there is still something lacking in those frameworks that I can't quite put my finger on.

Overall, though, I love CompoundJS with JugglinDB... but I tend to really love any framework I spend a lot of time with.

I'm guessing the downvotes are for the snideness of your remark. A more respectable way to phrase your question would've been to simply ask how this framework compares to some of the other well known Node frameworks and why might I look into Sails to solve a specific problem instead of some of the others that are available.

Thanks for your feedback. English is not my native language so I can sound rude unintentionally in written expression (it's hard enough already in my native language.)

I'll try throwing random smileys next time :P

Totally agree with you.

I think that there is some abuse of the term real-time these days:


Well the definition is Soft Real-Time (which may apply here) vs. Hard Real-Time (i.e. car ECU).

But having done university research work in the field of hard real-time systems I also think "naahh thats not real-time" every time I see some Web-Framework advertised as such. There is a big set of interesting problems in hard real-time systems: Complex scheduling algorithms, fault proctection and recovery, bus systems that are also able to fulfil your timing requirements....

If you spend some time doing this kind of work your had will wrap around different problems. You cannot take malloc granted, you always fear that the compiler does something wrong or that you better write that routine in inline ASM. Etc.

That said, I do a lot of stuff in python now and its refreshing, but I miss these problems a little bit.

> I think that there is some abuse of the term real-time these days:

From your link:



The usefulness of a result degrades after its deadline, thereby degrading the system's quality of service.


A lot of web applications are soft realtime. Chat, Stock updates, news updates...hell twitter and fb updates are soft realtime

Please stop calling anything on the internet real-time. Response time is not guaranteed here.

I guess you mean hard realtime. What usually on the web is called realtime is soft realtime IMHO.

Sure I get, but I think it just dilutes the meaning of the term "real-time" to use it in a soft context.

> Sure I get, but I think it just dilutes the meaning of the term "real-time" to use it in a soft context.

Soft realtime isn't a new thing. Chat has always been soft realtime.

Well I guess this depends on the context. Usually when I talk about real-time I talk about soft real-time and explicitly state "hard" when I talk about hard real-time (which I don't really do as I don't do hard real-time ;)).

I love how this is put together and packaged. The graphics, nice intro video, and very clear docs. Well done!

I wish more OSS projects would put more care in their docs. Adding more personality and character and just cleaning it up - making it feel more approachable.

This is pretty standard presentation for Node.js packages.

Oh really? As a non-Node.js guy, I would love to see some others. Can you show me some examples please?


Node.js packages are usually small and self-contained. Without typing/APIs Node relies heavily on documentation, so packages which are not well-documented will fall into oblivion quickly. Who'd write a OSS library which nobody can use?

My personal favorite, interactive docs!


I like these ones because of the straightforwardness:




And many more:






Almost all packages without a website have a README (npm spits out warnings if missing README):





Mocha's docs are pretty awful, actually. If you don't know how to use it when you start, the docs are not going to help, much. They're mostly buzzwords and examples that show (in limited cases) "what", but not "why", and give you no purchase for answering questions about how to structure things.

To be fair only one of these has a video

Well, not all projects show off on video. IMHO, a video is a sloooow way to present information. I'd rather skim through some examples/demos/interactive docs.

The whole point of Node/npm/Express (as a popular module) is its modularity. Node is not just about JS on the server, it reflects a paradigm shift -- a movement away from too much abstraction and magic back to lean and simple systems. And it's unbelievable fast.

Sorry to say but such frameworks and ideas are from the last decade (Rails was the main reason why I switched to Node).

Amen to that! You should consider putting together a little blog post about "the Node way." Way too many people are just porting their heavyweight frameworks from Ruby/PHP/Python and not realizing that successful Node apps are a series of tiny components (brilliantly managed by npm), not complex frameworks.

This is something that I spend a lot of time thinking about (for instance, how can we apply this to the organization of corporations?)..

The whole point of Node is evented I/O in JavaScript. That's it - it doesn't take a stance on frameworks.

The point of npm is ... to be a package manager.

Express is a framework. I admittedly don't know much about it, but I believe it basically has pluggable middleware, like Rails.

Not sure these things share the "point" you are claiming they do.

It's great Node has both framework choices and a wealth of small modules that do one thing. I think there's room for both.

There was a bit of snark in this comment with the "..." which I apologise for, but I think my point was fair. Trying to paint Node as an anti-framework ecosystem is disingenuous and this is clearly not a goal of either Node, npm or Express.

I love Node, and am consistently impressed by npm, but pretending that these technologies represent a "paradigm shift" and some sort of cohesive shift away from frameworks is faintly ridiculous.

If you work on a team and are faced with the task of creating a large app your choice is to pick a framework or create your own from libraries. I'd argue that a (good) framework is likely to be better because the conventions are likely clearer and better documented than anything you cook up yourself by combining libraries and filling in gaps with your own code.

I started using sails.js and I loved it. I'm new in node so I needed some starting point. Before that I was coding in php and used frameworks. I couldn't imagine working without one so I started to look into node frameworks. All of them have good sides and bad. But sails.js was the one which I loved from first sight. I don't know why but it looked so similar to php frameworks I used. It was very simple for me so I started working with it and contributing. Yeah this framework lacks some futures but it's only a time question when it gets better and better. Because I think this framework will become choice number 1 for starting coders. Good luck guys and nice job!

I've looked the past week into sails.js. It brings a really cool new way to MVC Frameworks and makes it easy to do certain aspects. What I missed (and that's why I'm using express.js now) is the documentation (lacking) and testability (lacking as well). Also the ORM is really lacking. I'd recommend the authors to look into an existing ORM (sequelize or node-orm2) instead of creating an own one.

Sails certainly needs more polishing but I look forward to use it in the future at some point, because I really like what it wants to accomplish.

If you like certain aspects (exposing models via REST, policies etc.) it's really easy to do in express.js as well.

Hi mweibel,

I originally used Sequelize, but we wanted (a) noSQL support and (b) a bundled in-memory database.

Waterline has very good test coverage, and it's professionally maintained by my Node.js studio, Balderdash. We invest heavily in its development, because it makes our client projects better and faster.

Happy to answer any other questions about why we built our own ORM.

Ok I understand the decision now. Surely both (sequelize and node-orm2) aren't the one and only solution yet but I needed some stuff to be supported which you didn't (yet), e.g. indexes or something like that.

Did you have a look at jugglingdb? I don't use it also because of similar reasons why I didn't want waterline but basicly I think it's more mature than waterline is.

I think old RailwayJS now CompoundJS has similar goals to look like Rails, yet bring goodness of NodeJS to the masses.


I tried it before when it was RailwayJS and it was really good and fast. I didn't do any major projects in it.

I really enjoy using CompoundJS for quick prototypes. Wish there was a larger community though; well, really, I wish any of the MVC nodeJS frameworks had the kind of community that Rails and Django have.

I agree. It will probably take someone making successful site and the word will get out. My experience with it was that it was super fast, very responsive, so I imagine it can handle more trafic then rails I am currently using. It is no rails as rails has features that are out of this world, but you often don't need those...

We've been using Sails in all of our client projects for the last year, so I guess we'll see what happens :)

Node is excellent from an architectural point of view, but I can't get over JavaScript. I really think web developers have Stockholm syndrome with this language.

I actually like Javascript. Aside from all the little warts, the only real problem I see is garbage collection and how easy it is to leak memory. OO does take a little more work, and it'd be nice if modules/dependencies were baked in, but IMO JS passes the Larry Wall test: Easy things are easy, and hard things are possible.

Doing simple JavaScript is easy. Doing JavaScript well, that scales and doesn't become a spaghetti mess is _hard_.

Having said that, there are a tonne of libraries and tools which make it much better these days. A language is only as good as the available libraries and there are some really good ones on npm.

What, particulary, do you find problematic?

Totally agree. I created Sails to provide us a clean way of solving the problem of building large projects for our clients.

JavaScript is a powerful seductress, I've fallen for her many times. I remember writing a js web server and web application framework when rhino came out. It was an awesome thing at first since I could turn tons of java code into one liners easily, but as my app grew over the several thousand line mark it became more of a hassle to find and remember the apis i was creating in this white fire of code genesis. Finally I started getting angry everytime I had to lookup my new methods for stuff and I said f this, tooling > *. My pace went to zero as code size increased, but with Java if anything it increases or at the very least stays constant. JS is great for my personal site and small projects, but if someone gave me 1 million and said build an app that you can iterate on that would be potentially huge for purpose X, I would use java.

Still though, I stare longingly into JS's eyes when she looks my way...

This is clearly the case with me, yes, since one can't really avoid JS.

Yep people can't like a language because you haven't figured it out.

Cool, looking forward to watching the projects progress!

Quick question: when demonstrating the socket.io piece, one aspect that differs with meteor is their ddp which only sends data diffs on a per client basis, not the entire subset as your demo showed. How are you planning to tackle that with any decent about of clients or data size?

Great question! I'm really pumped about more folks getting involved.

First off, you can manage pubsub as you like using Socket.io. The most important thing to realize about Sails is that we're not trying to be Meteor. This is for real, production projects, with a straightforward fallback to trusted technologies. How you manage publish and subscribe is completely up to you-- but if you're using the API blueprint, here's how it works from a pubsub perspective:

GET /user => the socket who issued this request is subscribed to the class room, and the instance rooms for all models returned (until the socket closes)

POST /user => the model created is "introduced" to the class room, subscribing all sockets connected to the class room, to IT. Then, all of the class room subscribers are notified that the new model has been created.

PUT /user/n => sockets subscribed to the instance room for the model being updated receive a message

DELETE /user/n => sockets subscribed to the instance room for the model being deleted receive a message and become unsubscribed

The "magic" here is actually just a controller- you can take a peek here (https://github.com/balderdashy/sails/blob/master/lib/scaffol...) for more about what's going on in the blueprint.

Cool project, but the syntax highlighting they are using makes it really difficult to read: http://cl.ly/image/0W2m1x1g2u29

The logo on the front page makes me feel old ...

jQuery rockstar anyone?

lol for anyone else like me who didn't remember the reference, it was back in '08: http://blog.jquery.com/2008/08/29/death-to-javascript-rock-s...

Cool project. Automatic API generation will be very helpful for quick prototypes.

Any example applications made with Sails? A chat app?

Not that we can show yet! But we are currently working on several large client projects that use Sails in production.

sails business case rev2.pptx ?


Look at the files on this desktop

Ah, we are a services company which helps brands and startups build web applications. Sails is an instrumental tool in making our team agile and effective, so I give presentations on that.

Applications are open for YC Summer 2019

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact