

Rails is just an API - maccman
http://blog.alexmaccaw.com/rails-is-just-and-api-and-that-s-ok

======
n8agrin
Let's say you have a website and let's say that website serves a lot of
traffic. Now let's say you relegate Rails to act as just your API because
clients are fast now and you want to do some new cool stuff with Javascript
also, you're convinced your site is more like an "application". So you build
this system and it works really well, except for one thing. The first time you
load the page it takes a second or two minimum to get the page loaded. That's
ok at first, but really soon it becomes annoying. So you do everything you can
with your client, caching whatever possible. You get the load time down to
something like 1s. That's better but still not great. Some static sites can
spit back pages in like 200ms (across the network!!) and that 800ms difference
is crucial to the overall feel and snappiness of your "application".
Eventually you give up, you keep the parts of the site that work well as a
client-side app, push the rendering back to the server because even though the
server is a long ways away from the client and even though clients are fast,
you can directly control how quickly the server builds a page and you can
optimize that to your heart's content. Now you've gotten your page loads way
way down to like 400ms. You're doing great, people love you and you've saved
the day. I've fabricated the numbers, but this story is based on truth,
because you know who you are? Twitter, Alex's employer.

That's not to say that Rails doesn't make a great API and that Alex doesn't
have a point. There certainly is a place for frontend applications out there
built on frameworks like Spine, Backbone or Ember (all great projects). Those
types of applications have their advantages in some cases. But, it's prudent
to be pragmatic and to recognize that the times where you truly need to build
a client driven application are few and for the other times Rails is still
great at serving up HTML.

~~~
mattmanser
Why does a client-side app hand wavingly take a second or two minimum to load
compared to the 400ms server-side rendered one?

Exactly the same work is taking place on the server apart from template
processing. It makes no sense. If your API is going to be taking 2 secs to
build a response, so will your server-side rendered one.

There's no real overhead to DOM insertion and simple template output. If
you're doing crazy stuff, it's going to take long wherever you do it.

Admittedly it's still very tricky to get it right at the moment. I also don't
really agree with the author's statement about desktop experiences in a
browser. I'm beginning to believe it's impossible, especially without the
native UX of the OS. I don't think we ever will have that experience as long
as there's an address bar, back buttons and all the other cruft at the top of
the screen. I think users may always see it as a web page and expect it to
_behave_ like a web page. Hopefully I'm wrong.

~~~
n8agrin
Good question. I should be clear and state that when I say 1-2s page load
times I meant the time from when one requests the page to when one can see it.
In general API requests are fast, what is slow is having to always deliver a
large JS bootstrap across the network (JS files, templates, etc) and then
having to make the relevant API requests to produce the UI. Caching is
generally touted as a good solution to this problem, but in my experience it
tends to be insufficient. Yahoo did an (older now) study showing that 40-60%
of visitors arrive at your site having an empty cache
([http://www.yuiblog.com/blog/2007/01/04/performance-
research-...](http://www.yuiblog.com/blog/2007/01/04/performance-research-
part-2/)). Another solution is to pre-fetch data for the UI and deliver that
with the bootstrap but it's still difficult to speed up a ~1 or ~2 MB
download. This is what really ends up killing the experience.

~~~
mbell
Bad design.

Only pull the bare minimum to render the initial page on the first request,
load everything else you need, when you need it, asynchronously in the
background. There is no way the 'bootstrap' is 1-2MB. There is absolutely no
reason to load every single bit of javascript you could ever need on the first
page load just like you don't load every image on your site on the first
request.

~~~
n8agrin
It's really easy to armchair-engineer and just declare bad design. What's
harder is to actually build a system that scales well in the _very_ unusual
circumstance that sites like Twitter, Google and Facebook find themselves in.

Let's take your solution: it's really difficult to build a development
environment that allows a large team to work efficiently which is not based on
having essentially a single bootstrap file when deployed in production. When
you break apart your files into smaller chunks you are asking your developers
to understand the intricacies of asynchronous loading of each file and impose
dependency management on everyone. This is a huge problem at Twitter's scale.

FWIW, Twitter did break apart their files into smaller chunks pretty
effectively using the Loadrunner project
(<https://github.com/danwrong/loadrunner>).

~~~
mattmanser
I do agree it's very hard still and that many of the 'it's just an API' posts
are wishful thinking for the next year or two.

However twitter is a perfect example of how not to do it, they inadvertently
shot themselves in the foot with the hashbangs so they never know in the first
request what's being asked for. That's kind of a mix between HTML5 history
being so slow to come out and Google encouraging the # stuff in the first
place. But everyone's still learning. Full page postback-less js applications
are still a pretty new field.

Twitter were a very early trail blazer. As much as people hate it, kudos to
them for having the balls to try it and let us all learn from their mistakes.
I've got a project that's a horrible mix between postback and postbackless
stuff. It's almost dailyWTF worthy, but I don't regret doing it as it's
getting closer to getting it done right. And there are people using it right
now and it works as much as I cringe about it.

For example if you look at the 1.5Mb js file they send when I do an anonymous
request, it's got every possible action I could ever do regardless of whether
you're on a tweet page, the main page, a profile page, etc. It doesn't matter
if I'm signed in or not. They're all in there as templates. And then for some
reason they wack in a load of compressed jQuery stuff, etc. It has how to sign
up, how to add people to follow, congratulation screen for when your first few
follows, etc.

That, to me, is just nuts. Why is there no split in the js dependant on the
kind of user they're going to be? On reflection they probably think that too.

With regards to development environments, I do think you should force your
programmers to understand your infrastructure. Give new programmers a couple
of simple examples to play with on how to manage dependencies and loading
files and that's that. In my view it's no different to saying 'we use these
parts of C++, not these' or 'this is our coding style, you must follow it or
your checkins will be rejected'. Or 'this is how the industry this app is for
works, these are the general business rules most of them have, this is the
general workflow'.

New programmers to your organisation always have to pick up some contextual
information over time. It's your job to train them in the most relevant key
information asap. I think far too often it's just a case of 'you're a
programmer you're smart, let's just throw you in at the deep end and see if
you can swim. Oh, why did you swim into the shark pen? Silly n00b.'. Very
relevant: <http://news.ycombinator.com/item?id=3736800>

------
bdunn
Not so fast.

The backend (i.e. Rails) still does almost everything it used to do:
validations, access control, session management, data crunching, and
everything else that you can't blindly trust a client to do. The real
difference with client-side applications is that instead of stitching together
view templates and sending back HTML documents, JSON objects are sent back for
the client to represent.

More (sometimes duplicate) stuff is added to the client - things like client-
side validations, and all the business logic and template code for the
purposes of presentation. But no one in their right mind would let their
backend blindly consume whatever it gets and persist it without question.

There's still plenty of responsibility for the backend.

~~~
orangechicken
Nowhere was this implied. The article says that Rails makes excellent RESTful
APIs. Of course your API should do validations, access control, etc. But,
Rails doesn't have to do (much) of the HTML given client-side MVC/MVVM
libraries like Backbone and KnockoutJS.

Leave the rendering of the app to the client. Leave the ins and outs of the
data to the API (driven by Rails, Node/Express/Railway, Django, what-have-
you).

That's definitely applicable to mobile and web apps.

~~~
jiggy2011
So, tell me again why we should be using HyperText Transfer Protocol for doing
something that has nothing to do with transferring hypertext?

It would make more sense just to pipe JSON through IRC since it's much less
verbose and was designed to be symmetrical (and session based) from the start.

~~~
mbell
>So, tell me again why we should be using HyperText Transfer Protocol for
doing something that has nothing to do with transferring hypertext?

Because its the best option. When WebSockets what whatever socket protocol
becomes ubiquitous you'll probably see less HTTP use.

------
lrobb
_The caveats in moving state to the client is that it's a huge perceptual
shift for developers, with a steep learning curve._

From my perspective we're coming full circle back to client/server desktop
apps... only instead of C++, we're doing it with js inside a browser
container... I've done ActiveX controls and Flash components... It's not that
much of a stretch.

~~~
hcarvalhoalves
Agree, althought I'm not fully convinced the web is fit for "web apps", or
that even "web apps" make sense. At least not with current technology.

Developing apps to run on the browser still implies a lot of redundancy: you
are forced to work with solutions that weren't created for interactive
applications in the first place (HTTP, DOM), limited to one language designed
by comitee (Javascript) and code reuse is minimal. Everything just feels
hackish (at best) compared to native frameworks (e.g., Apple's Cocoa), and in
the end it's hard to achieve good UX and compatibility.

I would rather see more people deploying native aplications with great UX
backed by REST APIs than shoe-horning apps into browsers (which break the
web).

~~~
jiggy2011
I think there are 4 reasons we are here.

1) Developers are worried that a user won't try their app if they have to
install something on their computer.

2) Compatibility , support anything that can render HTML , although this may
no longer be the case with the amount of chrome only apps I see.

3) Firewalls, you can get out on port 80 pretty much anywhere, that random
port number you decided to use for your app not so much.

4) A few years back web programming was seen as the "easy" way to get into
development since writing relatively limited PHP was a lot easier than
wrangling C++ and the Windows SDK. Therefor web developers reached critical
mass.

Java applets and Flash did a reasonable job with 1 and 2, but they seem to be
some of the most hated parts of the web, I think part of this may be because
they are see as "too powerful". People want the web to be lightweight.

~~~
hcarvalhoalves
The problem with Java applets and Flash is that they are a broken model inside
another broken model - they shoe-horn their own VMs to run applications inside
a browser. It's the ultimate hack.

The web, as it was originally envisioned, makes perfect sense: HTTP, URIs and
hypertext to provide navigable content, period. On the other hand, building
interactive applications by manipulating the DOM while reinveinting UI
patterns and widgets over and over again seems like a hack that grew to
enormous proportions.

I feel the reason why "web apps" are so popular is because it allows small
startups to develop more-or-less cross-compatible products faster and with
fewer resources than developing a webservice and then hiring 4 engineers: one
for a Windows client, one for a Mac client, one for a iOS client and one for
an Android client. The fact browsers all follow more-or-less the same
standards and they all run Javascript turned them on the "write once, run
everywhere" platform that Java failed to deliver, but in my opinion it's still
(very) far away from ideal.

~~~
eli_gottlieb
Frankly, I'm wondering how nice a GUI you can write inside Inferno. Just have
everyone install an Inferno client and serve your app as a mountable
filesystem containing the VM code to JIT as a binary file.

------
bretthopper
Strange that there's no mention of Rails new/potential "API only" mode:
[https://github.com/rails/rails/blob/efd557a60cd976ac17be9e23...](https://github.com/rails/rails/blob/efd557a60cd976ac17be9e238111a551599caeb5/railties/guides/source/api_app.textile)

This will make it much easier to only use Rails as an API and get rid of a lot
of the bloat/complexity people seem to complain about.

This was posted on edgeguides but it's since been removed some reason
(<http://edgeguides.rubyonrails.org/api_app.html>).

~~~
jashkenas
"API only" mode was removed (perhaps temporarily), here:
[https://github.com/rails/rails/commit/6db930cb5bbff9ad824590...](https://github.com/rails/rails/commit/6db930cb5bbff9ad824590b5844e04768de240b1)

~~~
rbxbx
<https://github.com/lightness/lightrail> would seem to be of interest :)

------
MatthewPhillips
This feels very conciliatory towards Rails, like that of a boss praising the
employee he just demoted.

I'm bearish on Rails because its maintainers _don't want it to just be an
API_. The fight to become the best backend API is much different than the
fight to become the best html server. Rails isn't even participating in the
fight. Rails has a lot of cruft not needed in an API, Sinatra or Express feel
much better for that.

~~~
bad_user

         Rails isn't even participating in the fight
    

It never did and it shouldn't.

Rails became popular because with it developers had the ability to cut down on
soul-sucking activities in their day to day jobs, like building yet another
authorization system, or yet another admin. That some people ran with it and
scaled it to its limits, that's only because they felt in love with its ease
of getting things done.

That's its main advantage. When it comes to getting things done, there's no
better alternative.

    
    
         The fight to become the best backend API 
         is much different than the fight to become the 
         best html server.
    

Basically the best backend API is the one that is the fastest / that scales
better both horizontally and vertically / that's more malleable to new
developments and protocols (e.g. SPDY, Websockets) / that has the least
overhead. From that point of view, if you're running on top of a VM that has a
GIL, or that doesn't support real thread-based concurrency, then the "battle"
is already lost.

So you see, there is no fight. That fight was won long ago by the JVM and the
frameworks that run on top of it. Every big website on the web right now
(except Microsoft-stuff), runs either on top of the JVM or with custom-baked
solutions written in C/C++.

That didn't stop people from building cool stuff on top of PHP, or Rails, or
Django, or every other platform that brought instant gratification, but that's
another point entirely and we are talking about "battles" here.

~~~
lloeki
_> Rails became popular because with it developers had the ability to cut down
on soul-sucking activities in their day to day jobs, like building yet another
authorization system, or yet another admin._

I beg your pardon, but... what?! Out of the box, Rails has none of this. Rails
is almost a meta-framework. Honestly taking your two examples: Devise is
horribly complicated and the half-dozen admin frameworks that had a hard time
crossing the 3.x line (which is not encouraging for the future) are either
generators, downright incomplete enough to be useful outside of a hello world,
or frameworks in themselves. I defy anyone beginning with Rails to set up
Devise and an admin system in less than half a day, let alone an hour. I'm not
trying to pick up a fight, but anecdotally compare this to Django, where
setting up both auth and admin is largely under 30min for a newcomer, easy,
with ample possibilities left ahead.

So although Rails helps a lot in various areas (like resource routing,
respond_to/with), but it still ends up being soul-sucking in numerous others
where you have to either delve into needlessly complicated stuff or implement
it yourself.

~~~
jshen
"but it still ends up being soul-sucking in numerous others where you have to
either delve into needlessly complicated stuff or implement it yourself."

This is a false equivalence IMO. With rails i spend far less time on
incidental complexity than I do with anything else I've tried.

------
phamilton
One thing I find interesting is the balance of the Rails model and the
Backbone model. On a new project, I generally have fat Rails models and skinny
Backbone models. On legacy projects, I put most of the logic into Backbone
(since I'd rather not tamper with a legacy backend) making liberal use of
parse() and toJSON() in order to get the model the way I want to use it.

Rails/Backbone will work well for the time being but I wonder which way the
balance will swing? Will we have fat Rails models or fat Backbone models? If
it is a fat Backbone model, then maybe direct database queries is the
solution, cutting out Rails entirely. CouchDB and others already support this
and could make it even simpler in the future.

~~~
MattRogish
The problem with fat client-side models is that allows malicious users to
potentially break your code. Inject bad things. Re-assign users. Etc.

We'll always need some sort of server-side last-mile, tamper-proof validation.
So given that, I'm not sure the benefit of duplicating it on the client side.

~~~
bdunn
This.

You duplicate validation logic on the client side in order to provide rapid
feedback to the user. But it's a huge mistake to not let the backend have the
final say.

~~~
krsunny
Are you saying duplicating code is ok if only to make the app appear faster?
I've often wondered that myself.

------
clemesha
This is how I feel about Flask. I've been using it with Backbone.js and they
make a great combo: Flask API serving JSON, and the rest of the logic on the
client.

~~~
eddie_the_head
You might find these demoes of Flask with pjax interesting then:

<http://flaskpjax.herokuapp.com/automobiles>

<https://bitbucket.org/a2c/pjax_flask/overview>

~~~
ch0wn
If you go down the API route, Flask-Restless[0] and simpleapi[1] are also
worth a look.

[0] <http://readthedocs.org/docs/flask-restless/en/latest/> [1]
<https://github.com/flosch/simpleapi>

~~~
Ecio78
Is there any of this solution that bundles with an easy mobile library/sdk? I
was asking for something like a semicomplete backend opensource solution here
<http://news.ycombinator.com/item?id=3735387> but unfortunately I got no
responses

------
ma2rten
I tried this approach and it's clearly attractive, but it also has some
disadvantages. I decided to switch back to rendering static HTML in Django
(not a Rails guy), with just a little JS on top for now. These are my main
reasons:

\- Debugging on every browser was quite painful. I tried to support IE7+ as
well. If a server-side code works, it works for everyone.

\- Frameworks on the client-side are not as developed as the server-side ones.
Also I am reluctant to introduce more client-side libraries than necessarily,
so I will end up coding a lot of stuff, that I can get for free in Django
otherwise.

\- The user will need to wait for the JS to load and execute until they see
something on the first pageload (at least in my implementation).

\- If there is a bug in the JS it's harder to get it logged.

~~~
mkmcdonald
Twitter is a perfect example of a "thick client". It's slow, bloated and
buggy. When _one_ typo is made in the JavaScript "bundle", the whole site
implodes, leaving the user with simply the navigation bar. When JavaScript is
turned off, most functionality is lost. I couldn't even log out after
disabling JavaScript because "/logout" pointed to a hash.

JavaScript being enabled is not an axiom. The client is a very unstable
platform when juxtaposed with the server. A lightweight client facilitates
flexibility.

------
crusso
Nice article... very timely and fits in with my perception of where I'm headed
with my own Rails development.

I usually just go with wherever the Rails team is taking the framework. For
some legacy sites, I may stick with wherever they're headed.

For new projects, I really view Rails as just the web api that feeds my
Backbone framework.

------
cicloid
The cherry on top is just coffescript and the new sourcemaps functionality
coming from browsers.

Even if you prefer vanilla javascript, still is an awesome combo.

------
akurilin
I'd love to know what people think the current "state of the art" stack is for
rich and highly scalable web applications, something that has been proven to
work great in production by big projects. Is it nginx + Rails + Backbone? When
I think of fast rich web apps, Facebook and StackOverflow come to mind, and as
far as I remember, neither use the above-mentioned tools (not that it means
they're bad in any way).

Just a couple of years ago Rails-generated HTML pages were super hot, and now
people are almost insulted if you don't have a fairly complex Javascript
framework running the show.

------
instakill
_So what's the future for Rails? If you talk to the likes of 37Signals and
GitHub, it's pjax and server side rendering. This involves fetching a partial
of HTML from the server with Ajax, updating the page and changing the URL with
HTML5 pushState._

I really hope not. Rails is awesome and I love it to bits, but I will hate to
have to use a framework that is massively invested in Ajax/Pjax. The reason
for this is simple: UX. Companies don't seem to understand that there's more
to the world than just America and America's top-notch Internet [1]. A lot of
web traffic comes from places where the connectivity is simply shit and
interfaces like Quora, GMail, Twitter et al that have so much functionality
with server-side JavaScript as a prerequisite make it seriously difficult to
have an enjoyable experience more often than not. If you've ever tried to
access Google Analytics on a 1mbps shared connection in a relatively populated
office, you'll know what I mean.

Yes of course Ajax and the interactivity and convenience it offers are
awesome, but they come at a massive expense, and this is something that will
be very saddening if Rails starts considering it as a major part of its core
sooner rather than later.

[1] Alright so it's not just America, but my point stands.

~~~
untog
Thing is, AJAX should _help_ with this stuff. No more wasteful page reloads
where 90% of the HTML is the same, etc. Granted, we don't see that all the
time, but the theory is sound.

------
troyk
Rails is overkill for an api, I think grape
<https://github.com/intridea/grape> has a lot of potential here.

Put node.js in front of something like grape and you have the best of both
worlds.

------
there
It took me a bit to realize this wasn't Dustin Curtis' website; is this a
theme or what?

~~~
Smudge
It's a magical theme exclusively available to the few who Dustin Curtis
personally invites onto the svbtle.com platform.

------
etrain
Let's talk about context switches here: OMG! it's going to be sooo hard for
developers to switch from a model where all the logic happens on the server
and where the client is just a dumb display to a model where the all the logic
happens on the client and the server just serves as a coordinator.

Oh wait. That already happened, and it was called the switch from mainframes
to PCs (or whatever the fuck you want to call it). The point is: developers
adapted, and got over it, and you will too.

The question I (and everyone in this community) have (or should have) is - are
there strong technical foundations for this switch? Is Javascript the right
client-side interpreted language to support every conceivable application over
the next 10 years? Is HTML the right display/templating language?

My answer: no, not at all. But it's hard as hell to fight the momentum of an
unstoppable force. Even with an immovable object.

------
instakill
Off-topic but: Anyone know if Alex is hosting the code for that Kudos widget
anywhere? Couldn't find it on his Github.

~~~
pyrhho
I didn't notice the 'kudos' button, but went to look at it, and accidentally
sent one. Makes me wonder how many of them were accidentally sent by people
hovering to see what it was... Aside from the hover-state triggering
irreversible action, it's a nice little interaction.

------
dhruvasagar
My only gripe with the shift to client side MVC frameworks and such (which
although I like!), is that it often makes handling security (from
authorization perspective) a bit difficult, at the end of the day I cannot
have my authorization based presentation logic in the front end since it can
be easily manipulated.

~~~
dkubb
I don't think anyone is advocating this kind of development. In general you
can't trust anything the client tells you, so to release information to a
client that has not provided proper authentication credentials to the server
is a mistake.

------
__abc
I love how the link to examples for, "the upside of this approach", is his own
book.

Now, put that aside, I do agree :)

------
zaius
The major reason I'm excited about this shift is the potential for higher
scalability out of the box. Instead of rendering pages, the server is just for
static pages and data. Instead of using a central server to render for each
user, it's distributed out to the computing power of all clients.

~~~
virtualeyes
Yes, agreed, generate static everything on first request; i.e. hit the
application server just 1X for live data and generate static file(s) that
represent the request on the front end server (httpd, nginx)

That leaves authentication and CRUD operations for the application server to
work on; the rest lives in-memory (via google mod_pagespeed, for example) on
the front end server.

I'm taking this approach as I like speed, and I don't yet trust the JVM enough
to handle tons of live requests and OOME on me while I'm out surfing ;-)

------
regularjack
What about graceful degradation? Making JavaScript a requirement instead of an
addition is plain wrong and goes against the essence of the Web.

~~~
rimantas
Only if "Web" for you consist of mostly static content. For others there is an
interesting thing called Web Applications. How do you gracefully degrade a
game done with all cool stuff HTML5 and friends offer?

~~~
regularjack
No, I'm not talking about static content, I am talking about dynamic content,
which is exactly what Rails is there for. If you only have static content you
don't even need Rails, just have the web server deliver it.

I was not talking about "Web Applications" either, which, FYI, are not the
same thing as dynamic content. I realize that he mentions in the post that
he's mostly talking about Web Applications, but then he's just stating the
obvious and the post title should be "For Web Applications, Rails is just an
API".

------
dblock
Decent post with the wrong conclusion. Why do I need an MVC to make a RESTful
API?

~~~
sbecker
MVC for server-side APIs is still useful because you still need separation of
concerns, validations, access control, session management, data crunching, etc
on the server.

