Rendering nothing on 404 in a Ruby on Rails api
I’m working on a JSON api for fetching reviews from security.dxw.com/, using the rails-api gem. When a plugin hasn’t been reviewed, the api (naturally) returns a 404, but what should the body contain?
I could return something like { error: "Review not found" }
, but I like things to be nice and clean, so I’d prefer to display nothing at all. I started out with an empty json array: {}
, then scaled back to an even more minimal nil
, but my colleague Philip pointed out to me that you can actually just tell Rails to render nothing at all:
def not_found
render nothing: true, status: 404
end
Nice and clean.
One final thing – usually Rails infers the content type from the content itself. With an empty response, it defaults to a content type of text/html
. To force it to return an application/json
content type we could specify the format inline in that render
call, but we can go one better and specify json as the default format in our routes file:
scope '/api', defaults: { format: :json } do
# ...
end
EDIT:
Philip Potter points out in the comments that an empty body isn’t actually valid json (think about it: a json parser would fail). And on the same lines, it’s probably not valid html either. While it would be nice to send no Content-Type
header at all, it turns out that this is added by Rack, and I’m not super-keen to write my own rack middleware layer for this.
text/plain
seems like a reasonable compromise. Also I’ve more recently come across the head
method which gives a more succinct way of sending a response without a body:
def not_found
head 404, "content_type" => 'text/plain'
end