When you click a button/link it usually sends an html request, which is defined by Accept
header:
def show
puts request.headers["Accept"]
# => "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7"
# ^^^^^^^^^
# it's an html request. it's up to you (and rails) to respond with html
# or ignore it and render something else.
end
By default, Rails will render show.html.erb
template and set Content-Type
header to text/html
.
Then you add show.json.jbuilder
. Now you can ask for a json response instead of an html:
// with javascript
fetch("/models/1" , { headers: { Accept: "application/json" } })
.then(response => response.json())
.then(json => console.log(json)) // do something with the response
// and in controller you can see
// request.headers["Accept"] # => "application/json"
It's a json request so rails will render a json template.
Rails also gives you a way to render a particular response without using headers. Just add .json
to the url. Accept: text/html
in this case is ignored by rails and it will render a json template.
I don't remember any internal/external api concepts in rails, just a request and response.
If you need to add more logic in the controller to handle different types of requests use respond_to
method:
def show
respond_to do |format|
format.html { render :different_template }
format.json { render json: {error: "i'm not an api."} }
end
end