Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are the best practices for designing a RESTful public API on Rails?

Rails comes with RESTful resources out of the box, but do you use those for your actual public API? If so, how would you accomplish versioning of your API i.e. example.com/api/v2/foo/bar?

like image 714
Zach Avatar asked Sep 27 '08 20:09

Zach


People also ask

What's a common best practice when designing RESTful APIs?

When you're designing a REST API, you should not use verbs in the endpoint paths. The endpoints should use nouns, signifying what each of them does. This is because HTTP methods such as GET , POST , PUT , PATCH , and DELETE are already in verb form for performing basic CRUD (Create, Read, Update, Delete) operations.

What is RESTful API rails?

REST stands for REpresentational State Transfer and describes resources (in our case URLs) on which we can perform actions. CRUD , which stands for Create, Read, Update, Delete, are the actions that we perform. Although, in Rails, REST and CRUD are bestest buddies, the two can work fine on their own.


1 Answers

Typically, APIs for my applications are indeed built on the same resources that make up the HTML interface. For some (not me), that might be just using the code that comes out of the scaffold generator—but regardless of whether I write it custom or let the generator handle it, there are very few instances where I expose resources only to the programmatic API and not to the end user view.

Versioning hasn't been a problem for the applications I've built so far, but I can think of two ways to implement it.

1) You could add routes with the prefix 'v1,' 'v2,' etc., that set a parameter that you can then access in the controller to specify the processing to occur:

in routes.rb:

map.resources :posts, :path_prefix => '/:version'

in posts_controller.rb

class PostsController < ApplicationController
  def index
    respond_to do |format|
      format.xml do
        if params[:version] == 'v1'
          # ...
        else
          # ...
        end
      end
    end
  end
end

2) You might also consider adding a custom response format for each version

in initializers/mime_types.rb

Mime::Type.register_alias "application/xml", :v1
Mime::Type.register_alias "application/xml", :v2

in posts_controller.rb

class PostsController < ApplicationController
  def index
    respond_to do |format|
      format.v1 do
        # ...
      end
      format.v2 do
        # ...
      end
    end
  end
end

The former would give you URLs like example.com/v1/posts.xml and example.com/v2/posts.xml; the latter would give you URLs like example.com/posts.v1 and example.com/posts.v2

like image 118
Ben Scofield Avatar answered Nov 03 '22 07:11

Ben Scofield