Sails.js: Realtime MVC framework for Node.js
balderdashy.github.com
balderdashy.github.com
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 diffHaving said that, I'm trying to pick up NodeJS soon, what frameworks would you recommend to start off with? Express?
It's less like rails/django and more like sinatra/flask.
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.
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)!
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.
# 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)
nice work btw, the end to end of it is attractive if somewhat magical.
Reference: https://www.owasp.org/index.php/Top_10_2013-A8-Cross-Site_Re...
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.
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.
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.
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.)
"GET request are not supposed to imply any modification on the serveur."
Remember C++ constness?
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.
http://eflorenzano.com/blog/2010/09/27/why-node-disappoints-...
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.
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.
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?
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'll try throwing random smileys next time :P
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.
From your link:
<quote>
Soft
The usefulness of a result degrades after its deadline, thereby degrading the system's quality of service.
<quote>
A lot of web applications are soft realtime. Chat, Stock updates, news updates...hell twitter and fb updates are soft realtime
Soft realtime isn't a new thing. Chat has always been soft realtime.
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.
Thanks!
My personal favorite, interactive docs!
I like these ones because of the straightforwardness:
And many more:
http://visionmedia.github.com/mocha/
http://learnboost.github.com/stylus/
Almost all packages without a website have a README (npm spits out warnings if missing README):
https://npmjs.org/package/request
https://npmjs.org/package/browserify
Sorry to say but such frameworks and ideas are from the last decade (Rails was the main reason why I switched to Node).
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 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.
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.
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.
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.
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 tried it before when it was RailwayJS and it was really good and fast. I didn't do any major projects in it.
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?
Still though, I stare longingly into JS's eyes when she looks my way...
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?
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.