Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Access raw request body as buffer #1302

Closed
1 task done
95th opened this issue Jun 26, 2022 · 4 comments · Fixed by #1316
Closed
1 task done

Access raw request body as buffer #1302

95th opened this issue Jun 26, 2022 · 4 comments · Fixed by #1316
Assignees
Labels
BREAKING CHANGE Pull request introducing breaking changes. feature scope:browser Related to MSW running in a browser scope:node Related to MSW running in Node

Comments

@95th
Copy link
Collaborator

95th commented Jun 26, 2022

Scope

Adds a new behavior

Compatibility

  • This is a breaking change

Feature description

Allow accessing raw request body as buffer

@95th 95th added the feature label Jun 26, 2022
@kettanaito
Copy link
Member

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:

  • Implement a polyfill for 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.
  • Investigate what is the state of 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.

@kettanaito
Copy link
Member

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 (mswjs/mswjs.io#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()

@kettanaito kettanaito added BREAKING CHANGE Pull request introducing breaking changes. scope:node Related to MSW running in Node scope:browser Related to MSW running in a browser labels Jul 4, 2022
@kettanaito kettanaito self-assigned this Jul 4, 2022
@kettanaito
Copy link
Member

Phase 1

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).

Phase 2

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.

@kettanaito
Copy link
Member

Released: v0.44.0 🎉

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
BREAKING CHANGE Pull request introducing breaking changes. feature scope:browser Related to MSW running in a browser scope:node Related to MSW running in Node
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants