Post redirections and the 307 status12th March 2020
Some days ago I was reading chapter 4 of The rails way 5 (a very good book about Ruby on Rails, even for experienced programmers IMO) this chapter is all about how rails routing and redirections work.
There was a paragraph in particular that got my attention...
If you ever need a 307 redirect, say, to continue processing a POST request in a different action, you can always accomplish your own custom redirect
... And I just knew it right away;
Is there any decision you made in the past that you wish you would have had more time to work on to "fix it right" and often think about how you could approach it differently?
Well, for me, there was one particular issue I often think about and if I had known the status 307 code before things were very different at this very moment.
What is this status for? well, the specification says:
The 307 (Temporary Redirect) status code indicates that the target resource resides temporarily under a different URI and the user agent MUST NOT change the request method if it performs an automatic redirection to that URI [...] The server SHOULD generate a Location header field in the response containing a URI reference for the different URI. The user agent MAY use the Location field value for automatic redirection.
Or what my brain first thought of YOU CAN DO REDIRECTS WITH A POST!
I'm going to let you think about an scenario where you could use this status....
... If nothing comes to your mind, I'm going to try to describe my past situation.
1. Application A has this POST endpoint that Application B needs to hit.
2. Application A has a before_action method that checks if Application B's agent is a mobile browser.
3. Application A does a redirection if a mobile agent is detected.
4. Application A loses the POST data from Application B after the redirection.
How can you achieve this redirection in Rails?
Easy peasy, check at this code:
class DemoController < ApplicationController def create # CODE THAT DOES OTHER STUFF # CODE THAT DOES OTHER STUFF # CODE THAT DOES OTHER STUFF redirect_to another_endpoint_url, status: :temporary_redirect end end
The specification says that a Location header should be generated by the server, this is done by the redirect_to, then we need to pass the status: :temporary_redirect or status: 307, and that's it!
This is how a request looks like when inspected in the browser
Request URL: http://localhost:3000/demo/create Request Method: POST Status Code: 307 Temporary Redirect ... ommitted data ... authenticity_token: TRNTx09YSoQwu6MAKoEVkNvFbBakiUBY2brwpJqE5rTW41UiN7WmtiiaMWukINUPjINaYS0IiRsyf6IXDoYHSQ== q: test commit: Search
Notice the Location in the response headers is now the new URI
And this is the following request made after the redirection
Request URL: http://localhost:3000/another_endpoint Request Method: POST ... ommitted data ... authenticity_token: TRNTx09YSoQwu6MAKoEVkNvFbBakiUBY2brwpJqE5rTW41UiN7WmtiiaMWukINUPjINaYS0IiRsyf6IXDoYHSQ== q: test commit: Search
Notice that the POST method is preserved along with the POST data.
This is super useful information that you don't often need but that can make a difference when trying to work around these situations.
I hope you can use this in your future endeavors :)