I got a GET URL that calls a controller method getInfo. It can be called by mydomain.com/getInfo.json?params=BLAHBLAH or mydomain.com/getInfo?params=BLAHBLAH
In the controller, is there a way to detect how the user called it?
Yes. Within the controller you can call the request.format
method to determine the format requested by the user.
If you need more than just the format, you can look at request.url
for the full URL. More details about the request
object can be found here.
Within your controller's specific method, you can respond to different formats - for example:
respond_to do |format|
format.html
format.json { render :json => @user }
end
You can respond to various formats (xml, js, json, etc) - you can get more information about respond_to and how to use it in your controller here:
http://apidock.com/rails/ActionController/MimeResponds/InstanceMethods/respond_to
Here is an actual somewhat contrived working example, that answers the question of how to detect if the call is JSON / XML API call vs an "HTML" call. (Accepted answer doesn't answer that question, just tells you how to respond to various formats)
# We can use this in a before_filter
skip_before_action :verify_authenticity_token, if: :api_request?
# Or in the action
def show
@user = if api_request?
User.where(api_token: params[:token]).first
else
User.find(params[:id])
end
respond_to do |format|
format.html
format.json { render :json => @user }
end
end
private
def api_request?
request.format.json? || request.format.xml?
end
Using a respond_to
sets different types of responses, but it doesn't tell your application how the call was made unless you add some extra code that does it (see below for a crude example, just to illustrate the point.)
I wouldn't recommend this, interrogating request
is much safer, and 10x times more useful, as the approach below is only useful much later in the request lifecycle ( right before the response is sent back to the client). If you have any logic in your before filters this wouldn't work at all.
# Have no way of using it in a before_filter
# In your controller
def show
# I want to know if the call was JSON API - right here
# This approach wouldn't help at all.
@user = User.find(params[:id])
respond_to do |format|
format.html { @api_request = false}
format.json { @api_request = true; render :json => @user }
end
end
def api_request?
@api_request
end
A list of ways to check for json
request.format == 'json'
request.format == :json
request.format.json?
request.path.match('json')
request.url.match('json')
respond_to do |format|
format.json { render json: [] }
end
You can also check if request was an ajax request
request.xhr?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With