Projects / Fern

GitHub

Fern is a DSL for writing REST APIs on top of Ruby on Rails.

Fern-API

Fern-API provides a simple DSL for defining API endpoints.

Defining Endpoints

Fern provides methods for get, head, post, patch, put, delete, and options.

The basic structure of a request looks like this:

get :index do
  request do
    # ...
  end
end

Fern-Parameters

Fern-Parameters provides basic query string parameter validation for a variety of common data types.

Request parameters are defined in a params block:

get :show do
  params do
    param :id, :integer, required: true
  end
  request do
    # ...
  end
end

While the raw params can still be accessed inside of your request block via the params variable, when declaring a params block for an endpoint, you should use params.validated instead.

For example, for the above endpoint, you could access the id via params.validated[:id].

The following param types are supported:

  • :string
  • :integer
  • :float
  • :boolean
  • :date
  • :datetime

The param method also accepts a number of optional arguments:

  • array
  • default
  • max
  • min
  • required
  • values
params do
  param :user_id, :integer, required: true
  param :sort, :string, default: 'id'
  param :limit, min: 1, max: 100, default: 10
  param :offset, min: 0, default: 0
  param :status, required: true, values: %w[pending active]
  param :account_ids, :integer, array: true
end

Fern-Documentation

Fern-Documentation is an experimental utility for automatically generating documentation from your Fern API.

Fern-Documentation provides the doc DSL method for specifying a documentation string for an endpoint.

get :index do
  doc %(
    Return a list of accounts.
  )
  # ...
end

Documentation can be generated by the fern:docs Rake task. The documentation will be output as markdown files in the doc/api directory.

Fern-Form

Forms are classes which accept a params hash as an argument to their constructor.

Fern-Form provides the form DSL method for declaring the form for an endpoint. The form will be instantiated automatically using the params hash from the action and can be accessed via @form.

get :create do
  form UserForm
  request do
    User.create!(@form.to_h)
  end
end
{
  "name": "Jane Doe"
}

Fern-Presenter

Presenters are classes which satisfy two criteria:

  • They accept a model instance as an argument to their constructor.
  • They implement an as_json method.

Fern-Presenter provides a presenter DSL method to declare a presenter for an endpoint, and a present DSL method to instantiate that presenter, call as_json, and automatically return the result.

get :show do
  params do
    param :id, Integer, required: true
  end
  presenter UserPresenter
  request do
    present User.find(declared[:id])
  end
end
{
  "name": "John Doe"
}

Presenting Lists

The present DSL method also accepts enumerables, in which case it will instantiate the presenter once for each element in the array.

get :index do
  presenter UserPresenter
  request do
    present User.all.to_a
  end
end
[
  {
    "name": "John Doe"
  },
  {
    "name": "Jane Doe"
  }
]