Introducing the Rails API Project
blog.steveklabnik.com
blog.steveklabnik.com
$ 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.
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.
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.
I hope to not be encouraging people to use HEAD soon.
There is a great post about this here: http://rubysource.com/rails-or-sinatra-the-best-of-both-worl...
This project aims to provide the integrated development experience of Rails targeted at an API or JavaScript-heavy use-case.
I personally use Rails extensively for these use-cases, which was my driving force behind creating the active_model_serializers gem with José Valim. José and I also worked together on a project at Strobe that used a stripped-down, more API-focused version of the runtime stack.
Since Rails 3, Rails has been flexible enough for anyone to do this sort of thing, but Rails is all about having good defaults and leveraging conventions. This project is an attempt to see whether a relentless focus on the API use-case will yield some conventions that benefit those of us who are not using Rails primarily to generate HTML.
I skimmed through the README. This project is picking up a default set of components needed for API. You can add or subtract components based on your needs. So instead of you cherry picking all your gems, you choose either none or some. For many people, having a default working set with non-needed components removed is good.
> Or using something barebones to begin with, like sinatra/padrino?
I have used sinatra and though I like it, I much prefer rails. Sinatra has its charm, but it's too open ended that in a big project, you end up creating half of rails yourself. Some people mount sinatra apps in their rails application, but I prefer letting Rails handle the api.
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...
It should be as transparent as possible. Frameworks like Rails should expose the highest level cryptographic features possible and enable them by default. Secure-by-default is just another flavor of convention over configuration.
Rails doesn't exactly have the greatest track record when it comes to crypto or security but especially since Rails 3 they've done a great job addressing the problems, IMO.
I don't doubt the integrity, diligence and efforts the Rails project is putting into security as a whole.
Secure defaults are very important. Crypto is important, but not all security is crypto.
In this particular case, and I don't claim that it applies everywhere, this transparency has a potential cost.
I agree that it should be as transparent as possible, and also prefer convention over configuration. But some time the convention means some added risk, and particularly an unknown risk (because by following the convention I don't even have to think about this risk). In such a case, I think configuration might be preferable. Conversely, for any built-in security to be transparent, it really needs to be watertight and fit 100% of the users. Otherwise it puts some users at a risk they are completely unaware of.
Yes, but you started off talking about crypto so that's what I'm going to address...
Unless you're a cryptographer (and even then), any time you're using any type of crypto the risk model in your head is probably going to be completely wrong. I recently blogged about this:
http://tonyarcieri.com/all-the-crypto-code-youve-ever-writte...
Unless you plan on becoming a crypto expert your best bet is leaving cryptography to the experts.
I didn't talk about crypto at all, and I don't see any connection whatsoever to this subject. Admittedly, even my comment was off-topic. Now it really goes way off.
(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.
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.
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.
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 ;)
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.
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.
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).
> 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.
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.
edit: thanks, guys!
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.
Rails-api churns out JSON, JS consumes it. I can think of performance being an issue.
What are the other issues?
Also, the pipeline has been re-written for Rails 4, but historically it's been kinda slow and buggy.
For an example of what I'm thinking about, rake-pipeline-web is interesting.
This works out awesomely for a few reasons. First, our deploys for our mobile app is just rsync. No fancy cap scripts. Second, its super easy to put the mobile app behind a CDN.
One wrinkle in this approach is how to deal with dependencies between the Rails API and a completely separate JS app. We hack around that be packaging up our mobile app as a rubygem so that we can manage the dependencies through bundler.
I highly recommend this approach. Its a great way to separate out an API team from a front-end app team. All of our future apps are going to be written this way, including an HTML5 rewrite of all of our visualizations (from flash).
We plan on writing up a bunch of blog posts on the workflow, so stay tuned :)
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
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?
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?
Part 1: http://techblog.tribesports.com/blog/2011/09/24/versioning-t... Part 2: http://techblog.tribesports.com/blog/2011/09/24/separating-a...
This is better as a separate thing. Maybe it could absorb the under-utilized ActiveResource subsystem.
1. rails-api (the gem) forms the core. 2. ActiveModel::Serializers is now under the same organization, and making them work well together is a big priority. 3. Other gems/JS libraries may be built as we see fit, and put under the project umbrella as well. 4. I am now in charge of it all. ;)
> Why is this is another project and not part of actionpack?
Both of these gems were originally in HEAD Rails, but David reverted them.
Will serializers be in the Rails 4 Gemfile at least?
There _is_ a library called ActiveModel::Serializers in Rails 4, but it's much worse than the implementation that we have in the rails-api organization.
The README itself says Rails::API is faster, so not sure why a simple benchmark to back that up isn't a good idea.
edit: It really boils down to another way to visualize the overhead vs just listing what's been removed.
"We are building an API. Rails has extra components which aren't used but might cause overhead. Here is how to remove it."
I think that's a valid enough use-case.
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.
Without all that callback spaghetti, how are you supposed to scale to roflmillions of users?
That's a tradeoff, and overall we're happy with it.
Express is decent enough, but it's barely an equal to Merb.
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.