OPTIONS HTTP Method in Ruby on Rails

The HTTP protocol includes the OPTIONS method, which does not seem to be widely used, but along with the Access-Control-Allow-Methods can allow a HATEOS API to hint what capabilities are currently available. A client using this API can now choose what to present to the user based upon which HTTP methods which are available and building create or update forms based upon the templates.

Additionally, according to the HTTP spec the OPTIONS calls must not be cached. Hence the content of the API could be cacheable while still allowing access controls to be indicated in the uncacheable OPTIONS headers and documents.

OPTIONS is not a method that Ruby on Rails supports by default but it can be made to work with appropriate routes and appropriate Controller class.

config/routes.rb

Api::Application.routes.draw do
  resource :resources
  match '/resources'     => 'resource#collection_options', via: [:options]
  match '/resources/:id' => 'resource#options', via: [:options]
end

app/controller/resources_controller.rb

class ResourcesController
  # Collection endpoints #######################################################
  before_filter :only => [:index, :collection_options] do
    headers['Access-Control-Allow-Methods'] = 'GET, POST, OPTIONS'
  end

  def index; end

  def collection_options
    render(json: {
      creation_field_with_options: [
        {val: 'value1', label: 'Value Number One'},
        {val: 'value2', label: 'Value Number Two'},
      ]
    })
  end

  # Resource endpoints #########################################################
  before_filter :except => [:index, :collection_options] do
    headers['Access-Control-Allow-Methods'] = 'GET, PUT, DELETE, OPTIONS'
  end

  def show; end
  def delete; end
  def update; end

  def options
    render(json: {
      update_field_with_options: [
        {val: 'value1', label: 'Value Number One'},
        {val: 'value2', label: 'Value Number Two'},
      ]
    })
  end
end

You can check the output of your endpoints with the following commands:

curl -v --request OPTIONS http://localhost:3000/resources
curl -v --request OPTIONS http://localhost:3000/resources/1111

in which should should see the allowed method heads and the JSON documents describing the allowed field data.

References