If you are building an API or any sort of web services, you often want to work with the raw, unchanged request body. For a long time, I used to add this helper method in my Rails controllers to access the the incoming request body.
def request_body
@request_body ||= (
request.body.rewind
request.body.read
)
end
Recently, in one of the code reviews at work, I came across the raw_post
method in Rails which does this for you. Here's what the method is doing behind the scenes.
# actionpack/lib/action_dispatch/http/request.rb
def raw_post
unless has_header? "RAW_POST_DATA"
set_header("RAW_POST_DATA", read_body_stream)
body_stream.rewind if body_stream.respond_to?(:rewind)
end
get_header "RAW_POST_DATA"
end
def read_body_stream
body_stream.rewind if body_stream.respond_to?(:rewind)
return body_stream.read if headers.key?("Transfer-Encoding") # Read body stream until EOF if "Transfer-Encoding" is present
body_stream.read(content_length)
end
In your Rails controller, you can access this method as follows:
request.raw_post
I am surprised I never ran into this method before, as it has existed in Rails for over two decades, and was introduced by none other than Tobias Lütke, the founder of Shopify! Quite a piece of open source history, isn't it?
That's a wrap. I hope you found this article helpful and you learned something new.
As always, if you have any questions or feedback, didn't understand something, or found a mistake, please leave a comment below or send me an email. I reply to all emails I get from developers, and I look forward to hearing from you.
If you'd like to receive future articles directly in your email, please subscribe to my blog. Your email is respected, never shared, rented, sold or spammed. If you're already a subscriber, thank you.