概要
Rails で API を作成するときに、URL 設計を気にすると思います。
例えは、ユーザ情報を操作する users API のエンドポイントを下記のようなパスで作成したいとします。
http://$(DNS)/api/v1/users
この場合、routes.rb をどう書くのか調べたところルーティングのメソッドに namespace と scope と言うものがありました。
この 2 つの使い方を簡単にまとめました。
namespace の使い方
namespace を使うときは、Controller に URL のパス同様に /api/v1/ のディレクトリを作成する必要があります。
$ tree app/controllers/
app/controllers/
├── api
│ └── v1
│ └── users_controller.rb
├── application_controller.rb
└── concerns
app/controllers/api/v1/users_controller.rb の中身は、module を使って URL のパス同様の構成にします。
$ cat app/controllers/api/v1/users_controller.rb
module Api
module V1
class UsersController < ApplicationController
def index
render json: { status: 200, message: 'Success' }
end
end
end
end
routes.rb は namespace を利用すると、このように記載できます。
$ cat config/routes.rb
Rails.application.routes.draw do
namespace :api do
namespace :v1 do
resources :users, only: :index
end
end
end
ルーティングを確認します。
ひとまず、作成したい API のエンドポイントが用意できました。
$ rake routes
Prefix Verb URI Pattern Controller#Action
api_v1_users GET /api/v1/users(.:format) api/v1/users#index
最後にエンドポイントにアクセスできるか確認してみます。
$ curl 'http://localhost/api/v1/users'
{"status":200,"message":"Success"}
出来ました!レスポンスに想定通りの結果が返ってきました!
scope の使い方
scope を使うときには、Controller にわざわざディレクトリを作成する必要はありません。そのままで大丈夫です。
$ tree app/controllers/
app/controllers/
├── application_controller.rb
├── concerns
└── users_controller.rb
app/controllers/users_controller.rb の中身もそのままで大丈夫です。
$ cat users_controller.rb
class UsersController < ApplicationController
def index
render json: { status: 200, message: 'Success' }
end
end
routes.rb は scope を利用すると、このように記載できます。
$ cat config/routes.rb
Rails.application.routes.draw do
scope :api do
scope :v1 do
resources :users, only: :index
end
end
end
ルーティングを確認します。
ひとまず、作成したい API のエンドポイントが用意できました。
$ rake routes
Prefix Verb URI Pattern Controller#Action
users GET /api/v1/users(.:format) users#index
最後に、エンドポイントにアクセスできるか確認してみます。
$ curl 'http://localhost/api/v1/users'
{"status":200,"message":"Success"}
こちらの方法でも、想定通りの結果を受けることが出来ました!
まとめ
namespace と scope で URL を設計する方法をまとめました。
routes.rb の記載方法はどちらも同じです。
大きく異なるのは namespace を利用するときは、Controller 内に実際の URL パスと同様のディレクトリ構成を作る必要があるという点です。
namespace と scope どちらを使って URL 設計すれば良いかは、アプリケーションによると思います。
例えば、Web サーバの機能の一部に API の機能が混じっているアプリケーションの場合、Contoroller 内に API 用のディレクトリを作成して、namespace を使った URL 設計を行うのが綺麗な気がします。
API 機能しかないアプリケーションであれば、コントローラー内にわざわざディレクトリを作成せずに、scope を使ってを URL 設計を使うのが綺麗な気がします。