Grape: not rails single

In this post, I would like to introduce you to Grape, a ruby-based web framework designed for quick and easy development of APIs, as well as a little discussion about the fate of Rails in light of the latest trends in web development.
Ruby = Ruby On Rails
It somehow happened that when mentioning ruby as a web development tool (and just as a scripting language) in front of many people who have something to do with this web development itself, if not a logo with the notorious white rails on red background, then the magic phrase Ruby On Rails for sure.
I do not dare to argue whether this is good or bad - this article is not for argument. I can say one thing with certainty - RoR had a huge impact on the development of web frameworks in general, and it is extremely difficult to overestimate this contribution.
BUT
But life does not stand still.
The web is becoming dynamic, mobile applications are becoming more and more important, the user needs to consume content “without leaving the cash desk”, that is, from the screen of his iPhone, Google Nexus, Huawei, enter the name of your phone.
And the sites themselves need qualitatively new approaches to the organization of user interactions and the presentation of content.
AngularJS, Ember, Meteor.js, Derby.js are technologies that anticipate the next breakthrough in site building, which can be compared with the “invention” of AJAX in the good old days.
Ruby developers need a powerful and at the same time easy-to-learn tool for developing the APIs that RoR once became for regular sites.
Let's get to the point!
Indeed, enough reasoning. Meet - Grape
This is a framework sharpened for API development, no Swiss knives.
But we must pay tribute, he can do the API very well.
I will try to list its main advantages:
- API DSL
- API versioning out of the box
- parameterization of methods with built-in validation
- automatic generation of OPTIONS (who met with CORS - will appreciate)
- transparent work with API formats
- built-in DSL for documentation
here is a far from complete list of tools that make life easier for an API developer when he uses Grape.
Code time
To get started, I’ll give an example of a simple application that at /hello/world.json will return {hello: 'world'}
Gemfile
source 'https://rubygems.org'
gem 'grape', github: 'intridea/grape'
gem 'rack', '~> 1.5.2'
gem 'thin', '~> 1.6.2'
hello_world.rb
require 'grape'
class HelloWorld < Grape::API
format :json
namespace :hello do
get :world do
{hello: 'world'}
end
end
end
config.ru
require_relative 'hello_world'
run HelloWorld
On my i5 with 16 GB of memory and HDD, this application starts somewhere in 400-700 ms. Here is a list of gems used:
Using i18n 0.6.11
Using json 1.8.1
Using minitest 5.4.1
Using thread_safe 0.3.4
Using tzinfo 1.2.2
Using activesupport 4.1.6
Using descendants_tracker 0.0.4
Using ice_nine 0.11.0
Using axiom-types 0.1.1
Using builder 3.2.2
Using coercible 1.0.0
Using daemons 1.1.9
Using equalizer 0.0.9
Using eventmachine 1.0.3
Using hashie 3.3.1
Using multi_json 1.10.1
Using multi_xml 0.5.5
Using rack 1.5.2
Using rack-accept 0.4.5
Using rack-mount 0.8.3
Using virtus 1.0.3
Using grape 0.9.1 from git://github.com/intridea/grape.git (at master)
Using thin 1.6.2
As you may have noticed, Grape has a wonderful thing called namespace. She is a group, resource, resources, segment - all for the convenience of reading code.
However, it can be used without parameters. It would seem, why? And here is an example:
namespace :authorized do
before { authorize! }
get :some_secret_data ...
end
group do
before { authorize! }
get :some_secret_data ...
end
It's like in the movie - "everything that happened in Las Vegas - stays in Las Vegas."
Inside groups, as well as namespaces, you can define before and after blocks that will be executed only for routes specified in these groups (and deeper).
Here is an example demonstrating the use of parameters:
params do
requires :first_name, type: String
requires :last_name, type: String
optional :birth_date, type: DateTime
end
post :register do
...
end
As for me, it’s clear without words. Management will not even get to the route if parameters that satisfy the described conditions are not transferred with the request. The best part is that all this with minimal modifications can be used to document the API. For instance:
desc 'User signup'
params do
requires :first_name, type: String, desc: 'First name'
requires :last_name, type: String, desc: 'Last name'
optional :birth_date, type: DateTime, desc: 'Date of birth'
end
post :register do
...
end
We kill immediately an entire bunch of birds with one stone - the code is documented in place, by connecting grape-swagger we get swagger-compatible documentation. Changed the code - the documentation has changed.
One of the many wonderful things that won me over at Grape is mount. Allows you to mount the previously described API in a new location:
mount.rb
class Mount < Grape::API
get :mounted do
{mounted: true}
end
end
mount.rb
require 'grape'
require_relative 'mount'
class HelloWorld < Grape::API
format :json
namespace :hello do
mount Mount
get :world do
{hello: 'world'}
end
end
end
As we all already understood, our route from the Mount class will be available at /hello/mounted.json
"Vague doubts torment me ..."
Of course, the volume of the average article, which does not cause a persistent yawning reflex, is hardly enough to talk about all the pros and cons of the framework. My task in the first place was to arouse interest in you - the project documentation is not bad, there should not be any difficulties with further study.
Also on the github page you can find a list of gems that can be used in conjunction with grape.
Epilogue
Until recently, the project had a small problem associated with the automatic reload of modified code in dev-mode. All Rails developers are used to it and in my opinion this is a must have feature. In issues on the github, this problem was voiced several times and it seems that some solutions were proposed on Rack :: Reloader and for use cases with Rails.
I will allow myself to mention my own solution, which was released just a couple of weeks ago, namely the grape-reload gem , intended for use in plain-rack stacks.
For grape version 0.9.0 and earlier, you can use the gem version 0.0.3, for later and the master branch of the framework, use the master branch of the gem repository.
If you will be interested in further articles devoted to this framework - do not forget to mention this in the comments. To all ruby, poson!
PS In the near future I will write an article on creating an API for todo-lists using a database. I admit that from this introductory article it is not clear what is the difference between this framework and Rails and why I do not compare it with Sinatra.
I will also try in the next article to benchmark applications on ActiveSupport :: Metal and Grape.