HTTP Verbs in Yesod Forms
The main function provided by the yesod-form library for processing form
submissions is runFormPost
.
As the name implies, this function processes POST
requests. But what if you
want to use a different verb, like PUT
? The library is a little confusing in
this way, because the post in runFormPost
doesn’t actually refer to the HTTP
method that triggered the execution of the handler code.
The point of runFormPost
is actually just about running the parser against the
request body, rather than the query string as would happen with runFormGet
.
Conceptually, this makes some sense as a design decision when you remember that
web browsers natively only support GET
and POST
as values of the method
attribute in HTML forms. The difference between those two values is perfectly
reflected in the design of the library — the values in the form are transferred
in either the query string or the request body respectively.
While HTML forms only support GET
and POST
natively, a typical Yesod
project will also support request method overriding, by applying a value
for the _method
parameter in the query string.
In Hamlet, this looks something like this.
<form method=post action=@?{(ExampleR, [("_method", "PUT")])}>
This form submission would then be routed to the appropriate handler.
putExampleR :: Handler Html
putExampleR = do
((result, form), enctype) <- runFormPost exampleForm
-- …
So, the browser sends a POST
request, but the application actually interprets
this as a PUT
request and routes it to the appropriate handler. We then process
the form in that handler with runFormPost
, because the data is still
transferred in the request body.