
Introducing the Rails API Project - tomdale
http://blog.steveklabnik.com/posts/2012-11-22-introducing-the-rails-api-project
======
ollysb
Wouldn't this be better as a new lightweight generator for the existing rails
project? i.e.

$ rails new api

instead of

$ rails new

My concern is that rails-api will diverge from rails and I'll be stuck having
to decide which is the easiest starting point where I want features from both.

~~~
steveklabnik2
It already is: <https://github.com/rails-api/rails-api#for-new-apps>

This is not a fork of Rails, it's just a set of plugins that work together
nicely. Luckily, all the work on Rails 3 means that Rails is super modular,
and it's easy to break off just the bits that you want. See Crafting Rails
Applications[1] for more on this topic.

1: <http://plataformatec.com.br/crafting-rails-applications>

------
viseztrance
A few days ago I found myself getting a rather strange git error while running
bundle after upgrading to the latest ruby. Turns out the active record
serializer gem was moved just hours earlier to this rails-api location without
any reason or notice. It was referenced by a git revision, because we needed
the latest changes and it was also encouraged in the readme (as it still is
now).

My issue with all this is that we already had tagged revisions in our
application and this basically broke our older builds on which we actually
relied on should things go wrong (the application is a rails engine).

So I think it would had been nice if this was announced earlier.

~~~
steveklabnik2
So sorry about this. I was travelling back from Europe, and we had to
coordinate between everyone who owned the various gems, so there was a bit of
overlap there.

I hope to not be encouraging people to use HEAD soon.

~~~
viseztrance
It's ok. I think we should had fork the repo and reference that in the first
place.

------
kungpoo
I'm not trying but be harsh but I've never really understood the need for this
project. I mean, Rails just boils down to a collection of gems right? So
wouldn't you be best just cherry-picking your own gems? Or using something
barebones to begin with, like sinatra/padrino?

~~~
felipesabino
Rails loads ton of stuff you don't need if dealing with a simples REST API,
for example... So yes, you could only start with sinatra/padrino and add the
things you want, or do like these guys and start with rails and remove
everything you do not need.

~~~
paulbjensen
I think that you've hit the nail on the head, and highlighted 2 differing
styles of building web apps within the Ruby community.

There is a great post about this here: [http://rubysource.com/rails-or-
sinatra-the-best-of-both-worl...](http://rubysource.com/rails-or-sinatra-the-
best-of-both-worlds/)

------
gingerlime
Seems like a great initiative. As a django user, I was using tastypie, which
sits on top of django for creating an API. I agree that it's nice to reduce
some fat, if it's really not necessary.

On a side note, and sorry for going off-topic, but referring to this comment

> Security: Rails detects and thwarts IP spoofing attacks and handles
> cryptographic signatures in a timing attack aware way. Don't know what an IP
> spoofing attack or a timing attack is? Exactly.

It's not completely transparent to developers, or it shouldn't be. If you're
not careful, your rails app _might be_ vulnerable to IP spoofing even now.

See <https://github.com/rails/rails/pull/7980> and
[http://blog.gingerlime.com/2012/rails-ip-spoofing-
vulnerabil...](http://blog.gingerlime.com/2012/rails-ip-spoofing-
vulnerabilities-and-protection/)

~~~
wycats
The good news is that the Rails project has a robust security process, and
because we handle IP spoofing, there's a place to discuss this vulnerability.

(See <http://rubyonrails.org/security> ; as a member of the security list, I
can verify that we take every report extremely seriously)

That means that long-term, the number of vulnerabilities in Rails apps
decrease, even for users unaware of the specific vulnerabilities. Again, that
doesn't mean that Rails apps will never be vulnerable, it just means that
you're sharing much of the responsibility for securing your app with many
others through a project that takes resolving security vulnerabilities
extremely seriously.

~~~
gingerlime
That's really good to know. I don't doubt the rails project has a good
security process. I wasn't aware of this page, but perhaps should have
searched better.

I believe that the security coordinator (Michael Koziarski) was actually
involved on the discussion around this on github, so I'm not sure whether this
needs to be forwarded to the email address again?

I'm not trying to make this into a huge issue, which in most setups and apps
most likely isn't. I do think it's important people are aware of this, and if
they are vulnerable they can and should protect themselves. I have suggested a
number of workarounds to address this issue on my post in hope that people use
those, whether or not the rails project as a whole is going to address the
issue.

------
tomblomfield
We're using this to build internal services - I'm currently wondering if
there's a best practice for taking querystring params and mapping them to an
ActiveRecord query.

Obviously, it's possible to build a "Searchable" module/class, but I wondered
if anyone has already solved this problem?

Eg, pagingation, querying on date-ranges, ordering, filtering etc.

~~~
steveklabnik
There's nothing like that in rails-api yet, but I can see how that'd be
useful, for sure.

------
carols10cents
Does the hypermedia support exist now, or is that a future goal? I couldn't
tell from your blog post whether the use of future tense "will" about most of
the features implies "when you use it" or "when we write it" ;)

I also didn't see much in the READMEs or open issues having to do with
hypermedia at a quick glance.

Also, LOL at steveklabnik2 ;)

~~~
steveklabnik2
> Does the hypermedia support exist now, or is that a future goal?

Future goal. There's nothing at the moment, but it's a case that we're
interested in. I'd love to talk about exactly what we need to do on the
mailing list.

> Also, LOL at steveklabnik2 ;)

Yeah, steveklabnik would still be almost in top 100 to this day, I just
looked. Sigh.

------
EvilTrout
As someone creating a large Javascript application with a Rails API, this
makes me very happy. Perfect timing!

~~~
steveklabnik2
Awesome. Please let me know how I can help you build your apps more
effectively.

------
disbelief
I've built quite a few Rails-based APIs recently, and one of the major pain
points (for me) has been the performance of generating the actual JSON in the
payloads. I've ended up with a modified JBuilder gem and using a subset of its
render methods, but performance is still pretty lack-lustre. Compared to
to_json, it's absolutely glacial!

I'm wondering how the serialization in rails-api performs in this regard? I'm
assuming as this is a core part of its differentiation from rails base, and so
it should be better than JBuilder. Has anyone run any benchmarks for JSON
rendering?

Forgive me if this is a naive question, this is the first I've heard of rails-
api and I haven't explored the source or tried it out as yet.

~~~
steveklabnik
It uses (well, encourages the use of) AMS, which, as I understand, is way
faster than JBuilder. Don't have a benchmark handy, though, as I haven't run
into this problem personally.

------
jasongullickson
We'll be taking this for a spin. I've been pushing for an API-driven site for
awhile but the case for that model was cinched when we started adding non-web
clients to our system.

A leaned-out Rails is a nice compliment to other bolt-on API options and fat
GUI-based API builders. Personally I prefer to start with something even
simpler, but the facts are you can cover more ground faster (and potentially
safer) with something like this vs. building your HTTP stack from scratch.

The Hypermedia stuff is most exciting to me, as hand-rolling that is a hard-
sell for many teams (if you have a system of any significant richness).

~~~
steveklabnik2
Awesome. Let me know how it goes, please. :)

> The Hypermedia stuff is most exciting to me,

Me too. There's nothing concrete here yet, but there's lots of space to
explore and good things to build. I really want us to be a leader in this
space.

~~~
grabastic
I'm very excited about this as well. Any hints about what's on the roadmap?

Would love to see easy versioning with custom mime types and link headers for
pagination and associated resources. Maybe that doesn't belong in core... but
it would still be pretty cool.

~~~
bploetz
My testing shows that versionist works just fine with rails-api apps to
provide versioning capabilities. If you run into any problems, please file an
issue.

<https://github.com/bploetz/versionist>

~~~
grabastic
thanks. i'll give it a try... it wasn't on my radar. :)

------
aaronbrethorst
What's the easiest way to make this work well with the asset pipeline assuming
I wanted to make a single page app hosted in the same project? Or should I
just not do that?

edit: thanks, guys!

~~~
steveklabnik2
The asset pipline isn't removed, so you don't need to do anything special.

That said, I don't think that it's ideal for heavy JS apps. Lots of possible
work that could be done in this area.

~~~
irahul
> That said, I don't think that it's ideal for heavy JS apps.

Rails-api churns out JSON, JS consumes it. I can think of performance being an
issue.

What are the other issues?

~~~
steveklabnik2
I've responded to your sibling.

------
hayksaakian
This is great, getting started guide would be nice too.

~~~
steveklabnik2
Thanks! Do you need something more than what's in the README[1], or do you
mean I should have linked it from my post?

1: <https://github.com/rails-api/rails-api#railsapi>

~~~
richardjordan
This has come at a time I'm looking at Grape mounted in a Rails app for an API
layer. Is there a simple way to explain to those of us with less API building
experience what the pros/cons are of using rails-api over something like the
Grape gem?

~~~
steveklabnik2
It's the exact same as Sinatra vs. Rails: build it all yourself vs. using a
framework that has it built for you.

------
themgt
We've had a lot of love recently for Goliath + Grape, e.g. see:
[https://github.com/postrank-
labs/goliath/blob/master/example...](https://github.com/postrank-
labs/goliath/blob/master/examples/grape/server.rb)

Goliath is it's own asynchronous app server, and it wraps around the nice
Grape API DSL. Works really well for little projects I'd rather write in ruby
than CoffeeScript + node.js

~~~
bascule
Goliath is not only relatively slow, it limits you to using libraries which
have both an EventMachine implementation _and_ an em-synchrony-style Fibered
wrapper around them, which is basically a scant fraction of the total Ruby
libraries available. This is pretty silly.

~~~
themgt
Yeah just async HTTP/TCP, databases, and system commands. Not anything anyone
really uses

~~~
bascule
There is certainly _not_ an EventMachine counterpart for every Ruby library
available today. Furthermore, the EventMachine versions of most libraries are
second class citizens compared to the synchronous versions of these libraries.

Goliath/em-synchrony make the situation even worse: now not only do you have
to have an EventMachine version of a library (which is already probably less
featureful and more poorly maintained than the synchronous version), you need
a version of that EventMachine library which has been wrapped with Fibers.
This means your pool of available libraries is even smaller and poorly
maintained than what was available with EventMachine, let alone what's
available with synchronous libraries. And all of this is to get you an API
which resembles what the synchronous libraries would've given you in the first
place.

Rails(-API) is designed to work with that rich ecosystem of well-maintained
synchronous libraries. Due to its design, Goliath can't work with them.

So the question is: why would you forego the synchronous library ecosystem in
Ruby to get "fake" synchronous libraries that only work with libraries that
are 1) built from the ground up against EventMachine 2) have been wrapped to
look like normal synchronous libraries em-synchrony style?

~~~
themgt
To have a ruby HTTP server with async request handling and semi-readable code?

------
tomblomfield
This looks great - I'll be trying it out for a project this week.

I'm still searching around for a good solution to API "views" or presenters
when I don't want to expose all of a model's attributes. Something like Rabl?
What do other people use?

~~~
steveklabnik2
The organization includes ActiveModel::Serializers, which is really important
for giving you normalized JavaScript output. Rabl is slow and manual, which is
the opposite of the Rails philosophy. Convention over Configuration wins every
time.

~~~
tomblomfield
ActiveModel::Serializers is exactly what I was looking for, thanks!

------
hakaaak
Rails-api isn't a new project, and the name of the project is misleading. It
provides a no-frills controller. Why is this is another project and not part
of actionpack?

~~~
astrodust
ActionPack already has enough debris in it that it's starting to look like a
typical suburban garage so crowded with boxes and nicknacks that there's no
room for the car it was intended for.

This is better as a separate thing. Maybe it could absorb the under-utilized
ActiveResource subsystem.

~~~
steveklabnik
ActiveResource is being pulled out of Rails 4 and being put into its own gem.

------
bretthopper
Would be interesting to see some simple benchmarks comparing a base JSON only
Rails app with Rails::API.

~~~
steveklabnik2
The problem with benchmarks is that they don't really correspond to reality.
Your app is not a simple test app. Your site will not be running on my MacBook
Air. Your users won't have the usage patterns my script does.

~~~
sjtgraham
This is true, but they're better than nothing.

~~~
bascule
A bad benchmark is worse than nothing

~~~
sjtgraham
What is bad about the OP'd suggest benchmark?

~~~
bascule
I'll just leave this here: <http://www.youtube.com/watch?v=xEJ1n13soWU>

------
SilasX
Whoa whoa whoa guys, timeout! I thought Rails enforced REST conventions on all
your models and therefore Gives You An API For Free? Wasn't that its big
selling point? Or of adhering to REST in general?

~~~
rahoulb
Rails doesn't enforce anything - but it does encourage you to follow a RESTful
style (not necessarily REST itself).

But the point of this is to strip out the defaults in Rails that are included
because they are convenient in full-blown apps, that aren't needed in apps
that only serve APIs (reducing bloat and probably making things faster). How
much of an issue those things are in a real application will vary.

From the article:

> we can remove many parts of Rails that aren't important in an API context:
> many middleware don't make sense, and all of ActionView can go away

...

> Similarly, the structure of ActionController::Base is interesting: it
> includes a ton of modules that implement various features. This means that
> we can build an alternate 'controller stack' that doesn't include all of the
> ones that are in Base.

------
louischatriot
Interesting project, but if you're only building an API, using a much more
lightweight combo such as nodejs + express seems better.

~~~
astrodust
I challenge you to build some non-toy API with Node.JS and then try the same
thing in Rails.

Express is decent enough, but it's barely an equal to Merb.

~~~
louischatriot
Challenge accepted: we have an API up and running at tldr.io :) We don't have
a gazillion hits everyday for sure, and it may not be as complex as Twitter
but: \- It works perfectly \- It really wasn't that difficult to build

~~~
astrodust
The second half of that challenge is to compare to how hard it would've been
in Rails.

~~~
louischatriot
I can also answer that as I've a fair bit of Rails experience. This time, we
built our API using nodejs/expressjs for the first time, so we had to learn it
plus the ins and outs of handling user login, sessions, CORS and a lot of
small things Rails does for you. So we wouls probably have been faster with
Rails.

If we need to build another product from scratch again though, we'll
definitely be faster with nodejs. I understand that nodejs programming seems
strange/hard to do in a non-spagetthi way to some people, but really, after a
few months it is not hard.

