I’m working on updating an application from Turbolinks/UJS to Turbo and have a few questions regarding the changes related to HTTP redirect responses (questions bolded below).
The documentation says my redirects should now return a HTTP 303 See Other
. From other research, I’ve come to understand that this is because when a HTTP 302 Found
is returned, it is pointing to the new location of the resource but it might be assumed that we still want to carry out the original HTTP method at that new location. OTOH, a 303 is not saying this is the new location for that originally requested resource, but instead the location is a different resource related to the request. Since it’s a different resource we should not assume the same HTTP method. I’m guess the assumed HTTP method to this new resource is a GET request so the client can presumably learn about this related resource before then possibly carrying out further actions on that resource using other HTTP methods?
This is of course different from how browsers operate. A browser form, sending a POST
request and receiving redirect response, issues a GET
request at the indicated location regardless of the type of redirect.
I’ve also see some indication from other research that this maybe only needs to be done on the destroy action. The template in Rails seems to support this as it only has :see_other
on destroy
but not create
and update
. Is this because the destroy trigger is a Turbo-enabled link in the default templates while the create and update are Turbo-enabled forms? Does Turbo when submitting a form try to emulate the behavior of a browser submission by following the redirect with a GET regardless of redirect type? Where is the behavior for that defined in the Turbo?
Then I came across this PR that seems to try make the type of redirect not matter. It seems to change the method on the fetch
call to always be a POST (if non-GET) and then encode the real HTTP method using the _method
param hack. Since POST
requests seem to emulate browser behavior in Turbo, does this mean that all Turbo requests (form or link regardless of method type) are good with any sort of redirect response? I’m assuming this part of turbo-rails and not Turbo proper since the _method
param hack is a Rails thing? Does this mean it should be a 303 response generally for Turbo but in the special case of using Turbo with Rails any sort of redirect will work? Testing this out in my application shows this to be the case. My destroy operates correctly without the :see_other
.
Finally, some semantic questions. Is the work on PR 370 just a crutch to help existing apps migrate to Turbo and greenfield development should be using :see_other
to be semantically correct even if the 302 works because of the crutch? It seems if we are going for semantic correctness why wouldn’t we also want to use see_other
on create
and update
actions? If :see_other
really should be returned for most responses to be semantically correct then is there a way to make that the default in Rails and then only use :found
if we really want to semantically indicate a resource is at a new location and the client should send their original HTTP method to that new location?