Skip to content

Instantly share code, notes, and snippets.

@radar
Created January 20, 2011 09:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save radar/787626 to your computer and use it in GitHub Desktop.
Save radar/787626 to your computer and use it in GitHub Desktop.

When I make a POST request to /api/v1/projects.json it returns an incorrect Location header. In my opinion, this should point to /api/v1/projects/1, not /projects/1, as APIs can then rely on this header to know how to re-locate this object if need be.

{
"Location"=>"http://example.org/projects/1", # WRONG WRONG WRONG
"Content-Type"=>"application/json; charset=utf-8",
"Cache-Control"=>"no-cache",
"X-UA-Compatible"=>"IE=Edge,chrome=1",
"X-Runtime"=>"0.012087"
}
def create
project = Project.create(params[:project])
respond_with(project, :location => api_v1_project_path(project) )
end
@zachinglis
Copy link

Agreed.

@jlecour
Copy link

jlecour commented Jan 20, 2011

+1

@sikachu
Copy link

sikachu commented Jan 20, 2011

Sad to say that, but I think you'll have to set :location for yourself

actionpack/lib/action_controller/metal/responder.rb

def api_behavior(error)
  raise error unless resourceful?

  if get?
    display resource
  elsif has_errors?
    display resource.errors, :status => :unprocessable_entity
  elsif post?
    display resource, :status => :created, :location => api_location # <== here
  elsif has_empty_resource_definition?
    display empty_resource, :status => :ok
  else
    head :ok
  end
end

def resource_location
  options[:location] || resources
end
alias :navigation_location :resource_location
alias :api_location :resource_location

@sikachu
Copy link

sikachu commented Jan 20, 2011

Seems like my finger went to fast:

app/controllers/api/v1/projects_controller.rb

respond_with(project, :location => api_v1_project_path(project))

I don't know if that's the expected behavior or not. But no, It doesn't use your current route as the location.

@pixeltrix
Copy link

Can't you override api_location in the controller?

@radar
Copy link
Author

radar commented Jan 20, 2011

apparently the right way to do this is to use sikachu's :location option. Works for me!

@sikachu
Copy link

sikachu commented Jan 20, 2011

@pixeltrix

Nope, as it's in the ActionController::Responder and not in the controller's context. ;)

@pixeltrix
Copy link

@sikachu you're right - what I should've said is that you can subclass ActionController::Responder and override it there. You can then assign your custom responder using self.responder = ApiResponder in your controller.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment