This seems very similar to Rails in structure and features, with the obvious upsides and downsides of Javascript and Node brought along. For me, the first Node framework to really catch my eye was Meteor. The live-updating, hot-code-pushing features seemed to really take advantage of the speed of V8, but I was put off by the total lack of MVC structure and other niceties of Rails (that are in Railway).
I'm still on the fence with Node and have yet to give it a real try. I think what will finally get me to jump in is something between the two. The sensibilities and structure of Rails with the great realtime features in Meteor. Just sayin.
EDIT: This does look fantastic by the way, a great contribution to the community.
Neat project! To echo what everyone else is saying, thanks for putting this out there.
I am curious as to what most HNers think of doing server side development in JS. It's obviously the flavor of the month, but I have yet to see the appeal. JS is certainly not a bad language, but it seems a lot more tedious than, say, ruby. The nesting of callbacks, the lack of built in OO infrastructure (given that most of us are trained with class based inheritance), the many quirks associated with making the language accessible to nonprogrammers. Am I missing something? Is there a really good reason to use JS on the server?
I use railway.js in production for a social bookmarking tool. I come from a rails background but a Rails API has some up and downs. I wanted to try node and have been very impressed. I use railway.js to serve up the iOS API (private beta) and the public beta website. It serves 800 reqs/min on a shared m1.small with one process and I've had no issues with it at all.
It plays a lot more smoothly with MongoDB and I find it far simpler to hook into more modern functionality with Websockets and client side JS rendering. I had a few issues with jugglingdb (which I forked and fixed) and it's all going smoothly.
I still use Rails for some sites but Node and railway.js let me bootstrap the whole API on MongoDB in a few days and get very acceptable performance.
The main reason Node.js is gaining popularity is because it is blazing fast, scales very well due to its IO + event driven architecture and it has the best support for websockets (see socket.io).
On the flip side, code can be hard to maintain and you need to be more disciplined so that you can read the code later otherwise it becomes a callback spaghetti. Doing everything through callbacks also requires a mental shift.
Like with everything in life, there are pros and cons and tradeoffs. So choose wisely :).
node.js isn't really that fast for traditional apps, but if you were to compare, it's pretty much on levels of nginx and it's actually slower serving static files. only in few cases node.js shows its power, i.e; real-time apps/games. i wouldn't build any full-blown websites in node.js. only a certain piece on the site i'd do it in node, like a widget or something.
Yep, you shouldn't be using node to serve static files anyway. This is something a reverse proxy such as nginx should do. Node can then be used to serve either as a pure API (serving json with express is the easiest way) for a webapp or render the webpages.
I agree about the CDN, even though for us performance is not so critical we need to use a CDN (yet). I didn't know node-http-proxy but it sounds interesting I'll check it out.
I agree. I would do the same but I couldn't find any examples of doing this on the web. One could potentially use Redis or a AMQP as a middleman to integrate node.js's push with a Rails app. If I get sometime on the weekend I would like to try this.
Perhaps I'm missing something but how is this a matter of opinion? If one wanted to avoid callbacks, which were the OC's original issue with node, one would break up the callback spaghetti into distinct, possibly prototyped objects, and glue them together with node's events. How is that any more difficult to maintain than, say, Python classes? If anything, I personally like the ability to choose the coding style with JS in this case, e.g. callbacks are great for quick prototyping when you can't be bothered to organize everything properly from the get-go.
In a language like Ruby or Python by using Fibers or Co-Routines(Greenlets), one can get benefit of non-blocking IO at the same time avoiding code spaghetti.
Gevent in python for example is pretty popular and similar is the case with Em-synchony in Ruby.
I have used callback objects but really that is not even close to what one can achieve with Fibers or Greenlets.
As silly as it sounds, one of my favorite aspects of Node is how ridiculously portable and modular it is. NPM makes everything a breeze, and (thanks to support from Microsoft) it actually allows easy development on Windows. I realize plenty of languages have their own package managers, but NPM is fantastic.
The callback aspect definitely requires more discipline, but I'm glad that I've learned it.
Nested callbacks naturally allows for non-blocking code, which leads to higher request capacity.
In, say, Ruby, you've got EventMachine for something equivalent but it's definitely "bolted" on to the language. Python has Twisted, with which I have no personal experience. In PHP, there are really no options.
If it's about higher request capacity, PHP scales horizontally with its share nothing, no application server architecture. I'm not advocating, just sayin'.
The Node / EventMachine / Twisted version of nonblocking IO is built on the Reactor Pattern. The common use case is to minimize IO delay. Whenever there is IO, a NodeJS script will cheerfully continue execution of other code, whereas in PHP and other purely synchronous languages, the script would block while waiting for the result. In practice, this has more use cases than just IO, of course. For example, one can send heavy computations to background processes and execute other code while waiting for the result.
So back to the original point, yes, writing nested callbacks can be more difficult to decipher than "flat" code, but the results may very well be worthwhile if you are looking to squeeze maximum performance out of your hardware.
I think the sweet spot for this kind of thing is when doing websockets. For a "normal" site, Rails is fine; it does a ton out of the box, and I like the language more than Javascript. However, the websocket story with Rails is not as clear as with something like Node, Erlang, or Go. This is worth repeating:
May be not as much clear. But Ruby world has plenty of options for Websocket as well. I have built production Websocket server on top of Goliath and Faye and it works like a charm.
Yeah, it's not like it's impossible with Ruby, but especially compared to a system like Erlang - to my way of thinking - it can start to look a bit clunky when you try and get lots of pieces talking to one another if, say, most of the rest of the application is in Rails. Or at least that's my impression, maybe I'm wrong?
I daresay you seem to have wrong impression. Having Rails app for typical web stuff and Eventmachine (em-synchrony) + faye stuff for realtime things work pretty well in actual usage. I can wrap DB calls, memcache/redis, SMTP connections etc inside my event loop and can achieve near same performance as a Node app.
The alternative of using node.js for everything sounds good but I am not really sure, how good node and its web frameworks are for building typical CRUD applications. Rails really solves building database backed applications problem pretty well.
I receive some kind of request in a Rails controller. I need to send, as a consequence, a notification via the web socket. How does it get from point A to point B? In Erlang, it's all likely to be quite contained and fast, and not involve writing anything to external queueing software, and to boot, it's all going to happen in the same unix process, rather than having one process that's the Rails server, and another that's the eventmachine server.
I don't know Node.js and how you'd handle sending messages from point A to point B, but I'd be interested in hearing some opinions.
Nested callbacks in JS means functions are first class members of the language..
...
thus
...
Functional programming is possible in JS..
...
thus
...
You can create beautiful abstractions with your code.
> It's a fact that you can create functional abstractions in JavaScript.
This is basically just restating "Javascript has first-class functions."
While first-class functions are nice, it's only the barest tip of the iceberg when it comes to what's needed for true functional programming. When you add more and stronger assumptions to your functions and types - referential transparency, static typing, immutable data structures - you get more and more back in functional expressive power and the tools that make it possible: memoization, concurrency, tail recursion, lazy evaluation, pattern matching, and so on.
The less assumptions you allow in the language, the more these powerful functional techniques and abstractions simply won't be possible. You still stand to gain from a modular, functional style, but you will have to go back to working around the inherently imperative language in most cases.
RailwayJS is cool, I used it for a long time, though I now use Locomotive as the latest git version is very good. It doesn't offer as many features but is clean and gets out your way.
I like locomotive because it stays out my way and allows me to work the way I want to. It's basically just Express 3 with an MVC layout, nicer routing, some nice helpers and a very clean and logical directory layout. It's how I would organise a new Express application if I was coding it from scratch!
I really like the idea of locomotive's 'initializers' directory - Any files you put in here are loaded at boot, in order. I use files in here to set up things like configuration, databases, logging, etc. With railwayjs these all ended up in the environment files which was hard to maintain.
The one thing I really didn't like in RailwayJS was the convention of putting all your database models inside one file (schema.js), I had to over-ride the built in ORM (JugglingDB) at the time because it was lacking features and define a customSchema() function to use mongoose, and this file ended up being really large and a bit of a mess. I tried separating things in to individual model files but I couldn't get it working without messing with RailwayJS code.
Probably a lot of the problems I had are now resolved as this was a few months ago, but I'm sticking with Locomotive from now on :)
First off, let me state that I in no way wish to diminish the accomplishments of the authors of RailwayJS in making these comments. I think they've built an inevitable framework given that Rails was (and likely still is) the most popular open source web framework (at least as far as the HN/startup crowd goes) and of course why not give developers the same abstractions they have with their old favorite when a new thing comes along. But here's a constructive observation:
Node.js isn't a framework. AND it's not a programming language. Node is ostensibly a set of libraries and a runtime environment. I've been to a few Node meetups over the past few years, and inevitably people (not just newbies btw) will ask "what will be the Rails for Node?" But I think making this analogy is wrong. It's wrong for two main reasons, the first of which is that it implicitly compares Node.js to Ruby, which is a category mistake. More importantly though I'd argue, it's wrong because making the Rails for Node analogy deprives the developer (you!) of the opportunity to allow an emergent programming paradigm to change the way you think about programming! So how should Node do that? My fantasy for how Node.js will evolve in the next few years is that it will be a series of node packages which can be easily dropped in and out of my programs. I believe that the goal of the third-party node package development community should be to encourage this modularity, because I think it is the right abstraction for what Node.js actually is, and not necessarily what some people might wish it was. It's easy enough to set up EventMachine in Rails and then you can use your familiar stack, but I'd encourage anyone looking to use Node.js to fully embrace it and use it as an opportunity to explore new workflows, and not just try to fit your old stack into an event loop.
Serious question: what's the point of all these Node.JS frameworks trying to mimic existing web framework functionality? Once you start adding synchronous database access, don't you lose more of the advantages of NodeJS anyway? Seems like all these frameworks appearing are trying to solve a problem already solved.
I've read some of the comments below and it seems there's some form of consensus that Node shines for the websocket.io portion of the web stack. So likely real use cases for NodeJS will using it in conjunction with your regular website?
Hey, I'm currently evaluating a number of Node.js web frameworks for a project I'm working on (I'll eventually publish the results on my blog). So far, I have reviewed: RailwayJS, Locomotive[0], Tower.js[1], GeddyJS[2], Derby[3] and Meteor[4]. It would be really great if you could give me your opinion on how RailwayJS compares to those (especially Tower.js, GeddyJS and Locomotive as they seem to be competing directly).
Well, I'm not impartial, so I wouldn't talk about pros and cons of RailwayJS in comparison to Geddy and Tower. I think "the framework" concept is wrong now, everyone should think in modular manner, both framework users and creators, because it allows to build really decent software. Rock solid frameworks are full of lie, slow and monsterous. So, my goal in railway - keep it modular and thin. After 1.5 years Railway is not Rails-like :) It just follows best part of it's ideology. But every new stuff I'm planning to add to framework will be added as modules.
For example now I'm working on "RIO" (railwayjs + socket.io) module, which will unobtrousively add socket.io capabilities to framework. It also solves auth and user-to-user communication problems.
Another big way to go - client side. We have some information about application structure that could be used in client-side, and duplication through backbone on client-side is awful idea, why not just give and transarent API for it. And this is separate module too, not bundled in railway.
So, this is a biggest difference in my opinion, anything other we implementing are basically the same.
> I think "the framework" concept is wrong now, everyone should think in modular manner
Definitely agree and that's why I am still undecided whether I want to use vanilla Express or a high level framework. RailwayJS is my top choice right now as it is built on top of Express and seems pretty modular. Tower also seems good but I dislike the fact that it is written in CoffeeScript.
FWIW, we couldn't get Socket.IO work out of the box. The transports didn't work/switch well and finally we gave up other transports and used "websockets" alone. Few people seems to have better results with SockJS than Socket.IO when we checked the community.
I'm still on the fence with Node and have yet to give it a real try. I think what will finally get me to jump in is something between the two. The sensibilities and structure of Rails with the great realtime features in Meteor. Just sayin.
EDIT: This does look fantastic by the way, a great contribution to the community.