Overriding request types (for handling PUTS submitted as POSTs from HTML forms)

32 views
Skip to first unread message

Oliver Mooney

unread,
Jul 31, 2015, 9:32:39 AM7/31/15
to Liberator
Hi,

The HTML5 form spec currently only allows for GET and POST actions when submitting forms. Is there any functionality to allow me to detect a POST request is actually a PUT or a DELETE request (via a hidden form field, for example?).  

One workaround I'm considering is treating PUTs as POSTs in all but name; PUTs are made to urls like /item/1, whereas new items are POSTed to /item so different resources for each URL could apply. Code bloat would also apply, plus much swearing in the code comments trying to explain all this.

Has anyone else used Liberator to handle PUT-analagous requests from web forms? Is there a standard way of doing it?

For reference there's a discussion of the absence of PUT & DELETE actions from HTML5 forms here:

Also some other web frameworks allow overriding of the method type with form or url parameters; see the second half of


Thanks,
Oliver.

Andrew Mcveigh

unread,
Aug 1, 2015, 7:15:18 AM8/1/15
to Liberator
One common way to do this is to use a hidden input named "_method" with the value PUT.

Then in liberator, you can override the :known-method? decision to check this form parameter, and change the :request-method on the request.

From there down your app will think the verb was PUT (or DELETE, or whatever).

Philipp Meier

unread,
Aug 1, 2015, 2:39:27 PM8/1/15
to Liberator


Am Freitag, 31. Juli 2015 15:32:39 UTC+2 schrieb Oliver Mooney:
The HTML5 form spec currently only allows for GET and POST actions when submitting forms. Is there any functionality to allow me to detect a POST request is actually a PUT or a DELETE request (via a hidden form field, for example?).  

One workaround I'm considering is treating PUTs as POSTs in all but name; PUTs are made to urls like /item/1, whereas new items are POSTed to /item so different resources for each URL could apply. Code bloat would also apply, plus much swearing in the code comments trying to explain all this.

I'd use some middleware around the liberator resource or even the routes
that would change the request method back based on a potential _method
header.

(defn wrap-force-method [h]
  (fn [{ps :params :as req}]
    (let [req (if-let [m (ps :_method)]
                (assoc req :request-method m)
                req)]
      (h req)))

This is untested and depends on wrap-params and wrap-keyword-params but
you should get the idea.
 
-billy. 

Oliver Mooney

unread,
Aug 4, 2015, 10:58:45 AM8/4/15
to Liberator
Billy, Andrew,

Thank you both for your pointers. I've a hidden field in the web form with the desired method coupled with some middleware & it works well.

I still feel like I'm twisting things out of shape slightly, but presumably that's common when trying to cater for non-compliant REST clients like this.

Cheers,
Oliver.
Reply all
Reply to author
Forward
0 new messages