The Rails 5 release is almost upon us, and it’s jammed packed with upgrades and new features. The one I’m most excited about is the Rails::API gem integration.
Rails::API and Rails 5
As a newcomer to Rails, I’m very excited for the soon-to-be released Rails 5. The main reason is that this might be the version I’ll be working with the most to develop my skills. Wanting to get a head start and have a deeper understanding of Rails, I cloned the current version and have had lots of fun exploring all the new features.
One of the features that excite me the most is the Rails::API integration. Using it has been tons of fun, not to mention super easy. So back in April a decision was made to integrate Rails::API gem into Rails core for the release for Rails 5. This new addition allows for an API-only Rails project that comes with a reduced middleware stack, lightweight controllers, and customised generators.
I’ve had a chance to play and have plenty of fun with the up-and-coming feature, so I’m going to share with you how I went about it and the pitfalls to avoid.
First thing to do is make sure you have Ruby 2.2.2+ as Rails 5 will require Ruby 2.2.2 or newer.
According to the Rails guide, you will be able to generate an API app using the following command:
$ rails new my_api --api
However this feature of Rails isn’t released yet so we have to generate our Rails API app using the latest version. Simply clone the master branch from the Rails repo.
To generate the project using
rails new I used the following command from the cloned Rails repo.
$ bundle exec railties/exe/rails new ~/repos/note-taking-api --api --edge
Sweet! Just like that we have a new API-only Rails 5 project. All we need to do now is run bundle and rake to install the gems and set up the database.
We need to make sure that we are running these commands using Rails 5 and not a previous version installed on our system. So run the executables from the bin folder
Scaffold the resource
$ bin/rails g scaffold note title note:text
When scaffolding or generating resources you don’t need any special arguments. If the app is built with the
--api flag, the generators should be customised to create the relevant files.
invoke active_record create db/migrate/20151002101900_create_notes.rb create app/modelels/note.rb invoke rspec create spec/models/note_spec.rb invoke factory_girl create spec/factories/notes.rb invoke resource_route route resources :notes create app/serializers/note_serializer.rb invoke scaffold_controller create app/controllers/notes_controller.rb invoke rspec create spec/controllers/notes_controller_spec.rb create spec/routing/notes_routing_spec.rb invoke rspec create spec/requests/notes_spec.rb
If the Active Model Serializers file didn’t get generated, you can use the command
bin/rails g serializer note title note to generate it.
All that is left now is to migrate and you can run the app so we can test the endpoints.
$ bin/rake db:migrate
With very little we have a simple CRUD API endpoint, which we can fire up and test these endpoints. I use the POSTMAN Chrome extension. However, you can use
curl from the terminal to be able to test it.
When you make get request after scaffolding the app you should get a blank response like so:
If you are following along and have tried to post, you may have ran into this NoMethodError (undefined method `permit!). In the notes_controller simply change:
def note_params params.require(:note).permit(:title, :note) end
def note_params params.permit(:title, :note) end
The last answer in this stackoverflow thread should explain it well.
I filled out the post request and sent through the raw data to the API path:
Change back to a get request to see the newly created notes:
Get a single note:
Put / Patch Request
An example of a put request:
An example of a patch request:
Keep in mind that both PUT and PATCH are routed to update. You can read this article which has a really good explanation of the difference between the two.
# PATCH/PUT /notes/1 def update if @note.update(note_params) render json: @note else render json: @note.errors, status: :unprocessable_entity end end
By default after deleting a note nothing is returned:
# DELETE /notes/1 def destroy @note.destroy end
This is fine but we need a way to let our app know that something happened. To keep this as simple as possible for now lets just return something after the deletion. We can pass no content(204) status code, which means that the server successfully processed the request, but is not returning any content. We can
render nothing: true, although when you use this, Rails still uses the status 200 by default so we need to pass through the status code of 204.
# DELETE /notes/1 def destroy @note.destroy render nothing: true, status: 204 end
That’s all folks!
As you can see, creating an API app with rails just got a lot easier. Keep in mind that it isn’t production ready and they still need to iron out a few bugs. Find out more below and see other example of the new feature.
The original pull request for the integration of the Rails::Api gem in to rails core.
Caching and throttling are useful aspects of an application. It is important to help serve API requests faster and also limit the amount of request that can be made.