How Rails Responds to `*/*`
Yesterday I fixed a bug in TIL. This application has a Twittercard, but it's never worked. Twitter's card validator confusingly claims the site lacks Twitter meta tags.
After experimenting, I realized that when cURL
-ing our site, the response type is application/json
. Why is Rails giving me JSON?
When an HTTP request's accept headers equal */*
, any MIME type is accepted. And, when a respond_to
block is present:
Rails determines the desired response format from the HTTP Accept header submitted by the client.
Determined how? I learned that the first MIME type declared is used for */*
requests.
Notice the difference (HTML first):
# app/controllers/posts_controller.rb
def index
@posts = Post.all
respond_to do |format|
format.html
format.json { render json: @posts }
end
end
Request/response:
$ curl -vI localhost:3000/
...
> Accept: */*
>
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
...
JSON first:
# app/controllers/posts_controller.rb
def index
@posts = Post.all
respond_to do |format|
format.json { render json: @posts }
format.html
end
end
Request/response:
$ curl -vI localhost:3000/
...
> Accept: */*
>
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
...
Reversing the order (HTML first) solved the issue.
Tweet