Ruby on Rails 5 api subdomain

為了要 demo api subdomain 的頁面是否能夠運作,這邊用鷹架隨便建立個東西。

1
2
rails g scaffold api::v1::books title
rake db:migrate

使用 constraints 限制 subdomain: 'api'

然後用 scope module: 'api' 加上 app/controllers/api 這個資料夾。

1
2
3
4
5
6
7
8
9
10
# config/routes.rb
Rails.application.routes.draw do
constraints subdomain: 'api' do
scope module: 'api' do
namespace :v1 do
resources :books
end
end
end
end

現在用瀏覽器去 http://api.localhost:3000/v1/books 頁面,會跳出 Routing Error 的錯誤。可是使用 rake routes 觀察的路徑卻是正確的。

1
2
3
4
5
6
7
8
9
10
# rake routes
Prefix Verb URI Pattern Controller#Action
api_v1_books GET /v1/books(.:format) api/v1/books#index {:subdomain=>"api"}
POST /v1/books(.:format) api/v1/books#create {:subdomain=>"api"}
new_api_v1_book GET /v1/books/new(.:format) api/v1/books#new {:subdomain=>"api"}
edit_api_v1_book GET /v1/books/:id/edit(.:format) api/v1/books#edit {:subdomain=>"api"}
api_v1_book GET /v1/books/:id(.:format) api/v1/books#show {:subdomain=>"api"}
PATCH /v1/books/:id(.:format) api/v1/books#update {:subdomain=>"api"}
PUT /v1/books/:id(.:format) api/v1/books#update {:subdomain=>"api"}
DELETE /v1/books/:id(.:format) api/v1/books#destroy {:subdomain=>"api"}

要解決這個錯誤,有兩個方法:

  1. lvh.me,去瀏覽 http://api.lvh.me:3000/v1/books 就能運作了。lvh.me 通常用來測試本地的網頁程式,解析的網址會是 127.0.0.1 可以用來測試 subdomain。

  2. config/environments/development.rb 調整 config.action_dispatch.tld_length = 0 預設為 1。然後去查看 https://api.localhost:3000/v1/books 頁面。

tld 是指 top level domain,以下是比較 tld_length 的差別:

1
2
3
4
5
6
7
8
9
10
11
# config.action_dispatch.tld_length = 1
request.host # => "api.localhost"
request.domain # => "api.localhost"
request.subdomain # => ""
request.subdomains # => []

# config.action_dispatch.tld_length = 0
request.host # => "localhost"
request.domain # => "localhost"
request.subdomain # => "api"
request.subdomains # => ["api"]