Kirill Zonov

Ruby on Grapes. Why did we choose Grape and why would I choose it again

February 01, 2018 | 8 Minute Read

Today I gave a talk on Ruby User Group Berlin meetup, here is a recap of it in a readable format. In my team, we are building a new and fast-evolving SPA product. We are small in terms of a number of developers and we are agile in terms of the market. We test the design of an idea, quickly implement it, test it with real users, then either keep and improve or change or remove. Quite a quick pace, so when we were choosing the web framework we wanted it to be more a helper for us rather than a box, out of which we cannot step.

Performance of ruby web frameworks

About language, it had been decided that it should be Ruby because it’s the fastest language for MVPs and fast pace development on pre-enterprise or pre-scale product steps. So the next we should choose a framework. What are the options? Ruby on Rails! Nah… We’re all tired of being a Rails developers and struggling with how to fit your app architecture into Rails, how to remove everything and keep just what you need. That’s feeling when you take opinionated Rails, opinionated developer and their opinions just doesn’t match %) BTW, I don’t say that Rails is bad. It begins to rot if don’t know how to cook it, so it’s all about developers, but we decided on the start we won’t go with Rails. So what are the other options:

  • Grape
  • Hanami
  • Roda
  • Rails API
  • Sinatra

And here are our criteria:

  • Comprehensiveness
  • Versioning support
  • Maturity
  • Performance
  • Personal preference

Comprehensiveness

By this term, I mean that the framework must have all the crucial things in it. Like CORS support, params validation, exceptions handling and rendering, i18n etc. Pretty obvious that Rails API as a project under the Rails ecosystem has everything needed. Sinatra as the opposite side is pretty barebone and doesn’t have much. You can add anything you’d like to, because it does not stop you from that, but it’s a bit of disadvantage by me. Just the overall idea of Sinatra is to have a minimal web app framework, which is great and I used it a lot, but I would like to have more tools out of the box. Other frameworks are somewhere in between, they all have enough of things out of the box as well as enough of side tools you can use with them, no much to say here.

Versioning support

Since we are evolving fast, it sometimes useful to build a new version of API and leave the old for some time, either to be able to still test it or just as some sort of a background to be able to revert back to. I see that path-based versioning makes perfect sense, so I consider it here (but you can also use header based). All the mentioned frameworks support you in versioning, but all of them in a different way: Sinatra, Hanami, Rails API:

namespace '/api/v1' do
  # routes goes here
end

Roda:

r.on "api" do
  r.on "v1" do
    r.is "users" do
      r.get do end
      r.post do end
    end
    r.get "comments" do end
  end
end

Grape:

version 'v1', using: :path

Personally, I prefer the way how Grape is doing it. Despite it’s more DSLish, but it’s less verbose and clear enough, so does not create any magic around.

Maturity

By this word I mean that the framework had been created not in the last month, has a stable version and I personally have no doubts that it will still exist in the next couple of years. Here are some numbers:

  • Grape. Had been released in 2010, has 4 merged PRs in the past month.
  • Rails API. Had been released in 2012, has 85 merged PRs in the past month, but keep in mind that it had been merged into Rails in 2015, so it's not just Rails API PRs.
  • Sinatra. Granddaddy here, had been released in 2008. Still evolving, 3 PRs in the last month. Personally, I don't see any changes in the past 5 years in it, but I didn't dig deep.
  • Hanami. Shiny new, had been released in 2014, but in my view area entered just in the past year because they released 1.0 version in on 2017. Under the active development, but just 1 PR in the last month. To be fair, I'll say that Grape actually also had been released under 1.0.0 version in the past year.
  • Roda. Started in 2014 and in the same year had first stable release. Has 1 merged PR in the last month.

Should you use any of these numbers when you consider choosing some web framework - up to you. By me, it shouldn’t be the main choice factor, but still nice to keep it in mind.

Performance

If you create a typical internet-startup product, web framework performance is the last thing you should think about. Even when you scale, the most bottlenecks you will have not with a framework, but with database queries or lack of caching, or inter-microservice communication or external providers which you by some reason touch in the main thread or whatever else. If it's somehow important for you: a couple of numbers are:
  • Grape development startup time is 0.81s on my machine
  • Rails API development startup time is 1.6s.
  • Sinatra expectedly the fastest with 0.27s. Surprise? Not at all!
Should you take it into consideration? Up to you again.

Personal preference

As I said, I used to work with both Rails and Rails API a lot, would work with it again if needed, but this time we decided to go without Rails. Again, I don't say that Rails is bad, btw it's almost a monopoly, and if you are alright with it - please read Piotr Solnica. Still now if I would need to build some MVP, which would not have long-term plans and wouldn't be SPA/API for mobile - I most likely would choose Rails. Sinatra is too barebone by me. It's good when already set up and you just need to develop a business logic around. But before that, you have to spend some time setting up the backbone. Hanami is a bit immature for the production product as by me, despite that, I enjoyed it in my learning pet project. About Roda, I just don't agree with the DSL they suggest for routing tree. So the Grape by me is perfectly fine. Fast to develop enough, has enough features, mature enough and fast enough to run tests and the web server xD

Some pigs among sheeps

DSL. Grape has its own DSL. Sometimes it's weird, like in their grape-entities. F.e.
expose :some_attribute, if: ->(element, _) { element.final? } do |element|
  element.my_attribute
end
Here I show you one presenter in which I want to expose some attribute which appears only on some condition and its name is different than it should be exposed in the API.

Some code samples

And just for you to understand better how does the API related code look like, here are two illustrations: api.rb routers/conversation.rb As you may see, you have built-in params validations, error rendering, versions and etc.

Conclusion

Obviously, there is no silver bullet in software engineering, and choosing the framework is more like a religious question, it's hard to convince another person to switch to it and leave his cozy world. But I encourage you to check out anything from the list I mentioned if you never tried. But if you're already experienced not only in Rails but somehow missed Grape, take a look at it, it's worth your time. Thank you! P.S. Slides:
Ruby on Grapes. Why did we choose Grape and why I would choose it again from graffzon