Yihang Ho bio photo

Yihang Ho

Coder

Twitter Github Email

I am releasing a plugin written for Ruby on Rails - require_params. require_params ensures that parameters that your Rails API actions require are present.

Rails 5 now officially supports API-only apps. API-only apps are Rails apps that respond with JSON instead of HTML.

We can think of API endpoints as functions - they take in some parameters, mutate some internal state, and output something. Currently, there is no way of ensuring that certain mandatory parameters are present. When they don't, I think the best course of action is as follow:

  • Respond with Bad Request
  • Give the client an error hash describing all required fields.

With these two, the client will know exactly what happened and how to fix it. By default, Rails will respond with Bad Request, but it doesn't tell the client what went wrong. To be more precise, in production mode, when params.require is called and the requested parameter is not present, an exception will be thrown. That exception will result in an empty respond with Bad Request. I think this is really not helpful for the API consumer.

To use require_params, simply call require_params with a list of required parameters. Options like only and except can be used to enforce the requirements only on certain actions:

class ApplicationController < ActionController::API
  include RequireParams
end

class UsersController
  require_params [:username, :password], only: [:create, :sign_in]
  require_params :email, only: :create
  require_params :session_token, except: [:create, :sign_in]

  def create
  end

  def sign_in
  end

  def update
  end
end

In your actions, you can assume that all the required parameters are present. Otherwise, your action will not be invoked at all and a useful error hash that looks like this will be presented to the client:

{
  "errors": {
    "username": ["is missing"],
    "password": ["is missing"]
  }
}