mirror of
https://github.com/metosin/reitit.git
synced 2025-12-18 08:51:12 +00:00
Create RESTful_form_methods.md
After a short conversation on the clojurians slack, this is an example of how to do the "RESTful form method" pattern with reitit.
This commit is contained in:
parent
71e83818b1
commit
091f9002fc
1 changed files with 36 additions and 0 deletions
36
doc/ring/RESTful_form_methods.md
Normal file
36
doc/ring/RESTful_form_methods.md
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
# RESTful form methods
|
||||||
|
|
||||||
|
When designing RESTful applications you will be doing a lot of "PATCH" and "DELETE" request, but most browsers don't support methods other than "GET" and "POST" when it comes to submitting forms.
|
||||||
|
|
||||||
|
There is a pattern to solve this (pioneered by Rails) using a hidden "_method" field in the form and swapping out the "POST" method for whatever is in that field.
|
||||||
|
|
||||||
|
We can do this with middleware in reitit like this:
|
||||||
|
```clj
|
||||||
|
(defn- hidden-method
|
||||||
|
[request]
|
||||||
|
(keyword
|
||||||
|
(or (get-in request [:form-params "_method"]) ;; look for "_method" field in :form-params
|
||||||
|
(get-in request [:multipart-params "_method"])))) ;; or in :multipart-params
|
||||||
|
|
||||||
|
(def wrap-hidden-method
|
||||||
|
{:name ::wrap-hidden-method
|
||||||
|
:wrap (fn [handler]
|
||||||
|
(fn [request]
|
||||||
|
(if-let [fm (and (= :post (:request-method request)) ;; if this is a :post request
|
||||||
|
(hidden-method request))] ;; and there is a "_method" field
|
||||||
|
(handler (assoc request :request-method fm)) ;; replace :request-method
|
||||||
|
(handler request))))})
|
||||||
|
```
|
||||||
|
|
||||||
|
And apply the middleware like this:
|
||||||
|
```clj
|
||||||
|
(reitit.ring/ring-handler
|
||||||
|
(reitit.ring/router ...)
|
||||||
|
(reitit.ring/create-default-handler)
|
||||||
|
{:middleware
|
||||||
|
[reitit.ring.middleware.parameters/parameters-middleware ;; needed to have :form-params in the request map
|
||||||
|
reitit.ring.middleware.multipart/multipart-middleware ;; needed to have :multipart-params in the request map
|
||||||
|
wrap-hidden-method]}) ;; our hidden method wrapper
|
||||||
|
```
|
||||||
|
(NOTE: This middleware must be placed here and not inside the route data given to `reitit.ring/handler`.
|
||||||
|
This is so that our middleware is applied before reitit matches the request with a spesific handler using the wrong method.)
|
||||||
Loading…
Reference in a new issue