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.

Setting up

First thing to do is make sure you have Ruby 2.2.2+ as Rails 5 will require Ruby 2.2.2 or newer.

App generation

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 bin/rake bin/rails

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

Test endpoints

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.

Post Request

When you make get request after scaffolding the app you should get a blank response like so:

Blank Get Rquest

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

to

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:

Post request

Get Request

Change back to a get request to see the newly created notes:

Full Get Request

Get a single note:

Single Note

Put / Patch Request

An example of a put request:

Patch request

An example of a patch request:

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

Delete Request

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

Deletion

That’s all folks!

Conclusion

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.

More reading

The original pull request for the integration of the Rails::Api gem in to rails core.

The Rails::API pull request

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.

Caching and Throttling an app

The two links below give an in-depth description of how to integrate the API endpoint with front-end Javascript apps.

Rails API with Backbone

Rails API with Ember