3

I'm trying to implement a collection resource with Liberator where a POST request to the collection URL (e.g. /posts) would create a new blog post item. That's working fine. What is not working is responding to the POST request with a 201 Created response including a Location header pointing to the new URL (e.g. /posts/1).

I can either respond with a 201 Created, but then I'm not able to include the Location header response, and hence the client won't know what the new URL is, or alternatively I can set :post-redirect? true, and return a 303 See Other response with a Location header.

Is there any way to return a 201 Created and the Location header from a Liberator POST handler?

liwp
  • 6,746
  • 1
  • 27
  • 39

1 Answers1

3

Every handler can return a full ring response including headers by using ring-response:

(defresource baz
  :method-allowed? true
  :new? true
  :exists? true
  :post! (fn [ctx] {::location "http://example.com"})
  :post-redirect? false 
  :handle-created (fn [{l ::location }] 
                    (ring-response {:headers {"Location" l}}))
ordnungswidrig
  • 3,140
  • 1
  • 18
  • 29
  • 1
    Thanks for the example, i like the separation between :post! and :handle-created. But the binding form in :handle-created should be (fn [{l ::location}] …) to compile correctly – squiddle Feb 11 '13 at 20:30
  • Returning `{:headers {"Location" "/test"}}` from `:handle-created` fn renders an HTML table body with the word "headers", instead of redirecting. – Petrus Theron Sep 25 '14 at 14:47
  • @pate, thanks for the comment, you actually need to wrap the response in ring-response to for the interpretation as a ring response – ordnungswidrig Oct 10 '14 at 09:34