I've been following this blog post on how to set up an api-only Rails 5 application. One of the sections talks about creating a subdomain for your api
Rails.application.routes.draw do
constraints subdomain: "api" do
scope module: "api" do
namespace :v1 do
resources :users
end
end
end
end
So that you can have namespacing and versioning like
http://api.my-website.com/v1/users
However, this seems to cause some issues locally. At first I just kept getting
back a 404 error that the route I was searching for didn't exist despite it
showing up correctly when I ran rake routes
Prefix Verb URI Pattern Controller#Action
v1_users GET /v1/users(.:format) api/v1/users#index {:subdomain=>"api"}
POST /v1/users(.:format) api/v1/users#create {:subdomain=>"api"}
v1_user GET /v1/users/:id(.:format) api/v1/users#show {:subdomain=>"api"}
PATCH /v1/users/:id(.:format) api/v1/users#update {:subdomain=>"api"}
PUT /v1/users/:id(.:format) api/v1/users#update {:subdomain=>"api"}
DELETE /v1/users/:id(.:format) api/v1/users#destroy {:subdomain=>"api"}
Removing constraints subdomain: "api"
gave back the correct response, allowing
me to prove to myself that this was indeed the issue.
- Editing
/etc/hosts
and adding in my subdomain to map to 127.0.0.1
As your machine gets started, it will need to know the mapping of some hostnames
to IP addresses before DNS can be referenced. This mapping is kept in the
/etc/hosts
file. In the absence of a name server, any network program on your
system consults this file to determine the IP address that corresponds to a host
name.
I had seen a few forums that mentioned this as a solution, so I added this to
/etc/hosts
127.0.0.1 api.dev.local
When I went to http://http://api.dev.local:3000/
all I got back from Chrome
was
Trying this URL on Firefox and Safari resulted in the same thing (Safari never ended up actually giving that error, it just "loaded" the page indefinitely).
- Using
lvh.me
andxip.io
I think this started with Tim Pope's invention of smackaho.st
, which was
simply a public domain pointed at 127.0.0.1 (localhost
). lvh.me
and xip.io
are just spawns of that same idea since both are
shorter and less offensive.
Unfortunately, lvh.me
returns the same connection refused error as mentioned
above and xip.io
hangs indefinitely.
- Changing proxy settings in Chrome to include
localhost
andlvh.me
Since I'm getting ERR_CONNECTION_REFUSED
and not ERR_EMPTY_RESPONSE
as would
be expected if the domain wasn't working, I figured this was some sort of
security check put in place by Chrome (and probably on Firefox and Safari too).
I tried ignoring the proxy settings for localhost
, lvh.io
, and xip.io
as per this
Stack Overflow answer. Nothing changed; I continued getting the same
connection error.
config.action_dispatch.tld_length sets the TLD (top-level domain) length for the application. Defaults to 1.
Setting config.action_dispatch.tld_length = 0
in config/environments/development.rb
.
Simple as that.
This works, although I am unsure of any unseen consequences with testing and
cookies in, as is noted upon in the answer.
Resources:
- http://www.chrisaitchison.com/2013/03/17/testing-subdomains-in-rails/
- http://stackoverflow.com/questions/7227845/localhost-not-working-in-chrome-and-firefox
- http://railscasts.com/episodes/221-subdomains-in-rails-3
- http://stackoverflow.com/questions/20095318/rails-4-subdomain-routing
If there is something you notice I am doing wrong, something you would like to add, or some question you may have, please feel free to comment on this post :)