Hanami has native REST support.

At the routing level, there are two methods that can be used to declare them: resources and resource. The former is for plural resources, the latter for singular ones.

Declaring a resource means to generate several default routes with just one line of code.

RESTful Resources

Default Routes

  1. # apps/web/config/routes.rb
  2. resources :books

It generates:

VerbPathActionNameNamed Route
GET/booksBooks::Index:index:books
GET/books/:idBooks::Show:show:book
GET/books/newBooks::New:new:new_book
POST/booksBooks::Create:create:books
GET/books/:id/editBooks::Edit:edit:edit_book
PATCH/books/:idBooks::Update:update:book
DELETE/books/:idBooks::Destroy:destroy:book

Remove Routes

In case we don’t need all the default routes we can use :only and pass one or more action names. We can also black list routes with :except.

  1. resources :books, only: [:new, :create, :show]
  2. # equivalent to
  3. resources :books, except: [:index, :edit, :update, :destroy]

Add Routes

Alongside with default routes we can specify extra routes for single (member) or multiple (collection) resources.

  1. resources :books do
  2. member do
  3. # Generates /books/1/toggle, maps to Books::Toggle, named :toggle_book
  4. get 'toggle'
  5. end
  6. collection do
  7. # Generates /books/search, maps to Books::Search, named :search_books
  8. get 'search'
  9. end
  10. end

Configure Controller

Imagine we have a controller named manuscripts, where we have actions like Manuscripts::Index, but we still want to expose those resources as /books. Using the :controller option will save our day.

  1. resources :books, controller: 'manuscripts'
  2. # GET /books/1 will route to Manuscripts::Show, etc.

RESTful Resource

  1. resource :account

It generates:

VerbPathActionNameNamed Route
GET/accountAccount::Show:show:account
GET/account/newAccount::New:new:new_account
POST/accountAccount::Create:create:account
GET/account/editAccount::Edit:edit:edit_account
PATCH/accountAccount::Update:update:account
DELETE/accountAccount::Destroy:destroy:account

Remove Routes

  1. resource :account, only: [:show, :edit, :update, :destroy]
  2. # equivalent to
  3. resource :account, except: [:new, :create]

Add Routes

  1. resource :account do
  2. member do
  3. # Generates /account/avatar, maps to Account::Avatar, named :avatar_account
  4. get 'avatar'
  5. end
  6. collection do
  7. # Generates /account/authorizations, maps to Account::Authorizations, named :authorizations_account
  8. get 'authorizations'
  9. end
  10. end

Configure Controller

  1. resource :account, controller: 'customer'

Nested Resource(s)

RESTful resource(s) can be nested in order to make available inner resources inside the scope of their parents.

Plural to plural

  1. resources :books do
  2. resources :reviews
  3. end

It generates default routes for books and the following ones.

VerbPathActionNameNamed Route
GET/books/:book_id/reviewsBooks::Reviews::Index:index:book_reviews
GET/books/:book_id/reviews/:idBooks::Reviews::Show:show:book_review
GET/books/:book_id/reviews/newBooks::Reviews::New:new:new_book_review
POST/books/:book_id/reviewsBooks::Reviews::Create:create:book_reviews
GET/books/:book_id/reviews/:id/editBooks::Reviews::Edit:edit:edit_book_review
PATCH/books/:book_id/reviews/:idBooks::Reviews::Update:update:book_review
DELETE/books/:book_id/reviews/:idBooks::Reviews::Destroy:destroy:book_review

Plural to singular

  1. resources :books do
  2. resource :cover
  3. end

It generates default routes for books and the following ones.

VerbPathActionNameNamed Route
GET/books/:book_id/coverBooks::Cover::Show:show:book_cover
GET/books/:book_id/cover/newBooks::Cover::New:new:new_book_cover
POST/books/:book_id/coverBooks::Cover::Create:create:book_cover
GET/books/:book_id/cover/editBooks::Cover::Edit:edit:edit_book_cover
PATCH/books/:book_id/coverBooks::Cover::Update:update:book_cover
DELETE/books/:book_id/coverBooks::Cover::Destroy:destroy:book_cover

Singular To Plural

  1. resource :account do
  2. resources :api_keys
  3. end

It generates default routes for account and the following ones.

VerbPathActionNameNamed Route
GET/account/api_keysAccount::ApiKeys::Index:index:account_api_keys
GET/account/api_keys/:idAccount::ApiKeys::Show:show:account_api_key
GET/account/api_keys/newAccount::ApiKeys::New:new:new_account_api_key
POST/account/api_keysAccount::ApiKeys::Create:create:account_api_keys
GET/account/api_keys/:id/editAccount::ApiKeys::Edit:edit:edit_account_api_key
PATCH/account/api_keys/:idAccount::ApiKeys::Update:update:account_api_key
DELETE/account/api_keys/:idAccount::ApiKeys::Destroy:destroy:account_api_key

Singular To Singular

  1. resource :account do
  2. resource :avatar
  3. end

It generates default routes for account and the following ones.

VerbPathActionNameNamed Route
GET/account/avatarAccount::Avatar::Show:show:account_avatar
GET/account/avatar/newAccount::Avatar::New:new:new_account_avatar
POST/account/avatarAccount::Avatar::Create:create:account_avatar
GET/account/avatar/editAccount::Avatar::Edit:edit:edit_account_avatar
PATCH/account/avatarAccount::Avatar::Update:update:account_avatar
DELETE/account/avatarAccount::Avatar::Destroy:destroy:account_avatar