Closed 95th closed 2 years ago
Hey, @95th. Thanks for raising this.
We currently handle all request/response bodies as strings. This has been a limitation imposed by the message channel between the worker and the client, but I have recently learned that that's not the case. You can send ReadableStream
via the message/broadcast channels as well, which will allow us to send any kind of request/response data between the worker and the client. I've opened the proof of concept to adopt readable streams for internal communication in #1288.
Focusing on the request body in particular, the req.body
is also either a string or a parsed JSON (based on your Content-Type
request header) right now. That is not ideal as people may be sending other types of data like binary of buffers. Despite MSW attempting to read them, I don't think that'd work reliably as some data may get corrupt along the way.
What I'd love to have is to extend a default fetch Request
instance, providing it with a buffer as an input. That way our users could do req.text()
or req.json()
without MSW assuming much about the media type of the request/response bodies. That is a concept I would love to see us try! Would you like to give it a go by opening a new pull request?
There are challenges to this, of course. As MSW executes the same handlers in both browser and Node, it wouldn't be able to do new Request()
because that class doesn't exist in Node (at least in v14, which we still support). I see two routes here:
Request
that can execute in any environment. Handle request body as buffers and have methods like text
/json
/etc. that convert that buffer to the respective data output.Request
support in Node, and if we can use it in Node 16, consider dropping the support for Node 14. This is a long-term strategy, and it may take years to get fully done. We've finished with the preparations for this on the interceptor's side. Will roll this out to MSW as the next step.
Meanwhile, I've opened a pull request (https://github.com/mswjs/mswjs.io/pull/207) that updates the docs on how to read the request body after this change.
-req.body
+await req.text()
+await req.json()
+await req.arrayBuffer()
To preserve backward compatibility, we will keep req.body
in the next version but should display a deprecation warning whenever it's accessed. Something like:
[MSW] Warning: reading request body as "req.body" is deprecated and will be removed in future versions. Please read the request body as plain text, JSON, or ArrayBuffer according to the Fetch API Request specification: https://developer.mozilla.org/en-US/docs/Web/API/Request
@95th, this deprecation may be tricky to implement since IsomorphicRequest
also has a private body
property. I was thinking to add a body
as a getter on MockedRequest
but if we extend IR, we will be overriding what this.body
does in the underlying IR as well with this deprecation warning.
One of the ways we could approach this is by moving this.body
to this._body
in IsomorphicRequest
, as we are not intending on exposing body
as a public property just now (doesn't expose the readable stream as per the specification).
I think we need to let the req.body
deprecation sink in for a while, so developers have a chance to notice it and migrate from it. I'd leave it for the next 3-4 minor versions and then remove it completely alongside the entire req.body
property.
This has been released in v0.44.0!
Make sure to always update to the latest version (npm i msw@latest
) to get the newest features and bug fixes.
Predictable release automation by @ossjs/release.
when is use +await req.json()
i got error
SyntaxError: Unexpected token 'o', "[object ArrayBuffer]" is not valid JSON
How can i resolve this issue?
my version is 1.1.0
oh my mistake my serviceWoreker.js file version and msw version is different! thx
Scope
Adds a new behavior
Compatibility
Feature description
Allow accessing raw request body as buffer