mswjs / msw

Industry standard API mocking for JavaScript.
https://mswjs.io
MIT License
16.04k stars 525 forks source link

Access raw request body as buffer #1302

Closed 95th closed 2 years ago

95th commented 2 years ago

Scope

Adds a new behavior

Compatibility

Feature description

Allow accessing raw request body as buffer

kettanaito commented 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:

kettanaito commented 2 years ago

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()
kettanaito commented 2 years ago

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 commented 2 years ago

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.

flex-hyuntae commented 2 months ago

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?

flex-hyuntae commented 2 months ago
스크린샷 2024-09-26 오후 3 10 02

my version is 1.1.0

flex-hyuntae commented 2 months ago

oh my mistake my serviceWoreker.js file version and msw version is different! thx