Question: Should we use msw to mock server-side apis based on the request body? #2148
-
Hello, msw team! We love msw and we think we should use it for a project. However, this project's setup feels a bit abnormal (maybe an understatement) and we're not sure if msw is the best choice or if we are thinking about this correctly. To summarize, we are using React on the frontend. We make requests via axios with a body to a single endpoint e.g. site.com/api. A server-side controller then takes over and sends the request to where it needs to go through internal server-side apis. Example: // request from a component
export function getInfo(params) {
return axiosInstance({
method: "POST",
baseURL: "https://site.com/api/",
data: {
action: "GET",
path: `info${handleQueryParams(params)}`,
},
});
} To mock this with msw, we would intercept the export const handler = [
// capture request to site.com/api
http.post("/api", async ({ request }) => {
// get request body
const requestJson = await request.json();
// get url
const url = new URL("https://placeholderurl.com/" + requestJson.path);
// get response from responseMap using pathname as the key
const response = responseMap[url.pathname];
// return response data
return HttpResponse.json(response);
}),
];
export const responseMap = {
"/info": {
name: "John Doe",
email: "[email protected]",
},
}; This "works" but I guess I'd just like to check with the professionals to see that there isn't a better way. This convoluted mess is probably just because of our backend setup and lack of a true RESTful api for us to access on the frontend. Thank you in advance for any help and insight that you are willing to give! 🙇 Edit: It's probably better to send another request from the site.com/api handler to another msw intercepted endpoint |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
Hi, @ellsworthjc. Thank you for your kinds words! You can choose whichever setup makes sense in the context of your request client, so what you've showcased makes sense if the request body contains the predicate as to how to handle the outgoing requests. That being said, I feel you can take advantage of MSW's built-in routing if you unfold the requests. Let me show you how. export const handler = [
// This is a generic handler that captures the
// immediate requests your app makes and "unfolds" them.
http.post('/api', async ({ request }) => {
const requestJson = await request.json()
const url = new URL('https://placeholder.com/' + requestJson.path)
const proxiedRequest = new Request(url, {
method: requestJson.action,
body: requestJson.data // check this with your request structure
})
// Instead of looking up the response from a map,
// perform that request immediately. This will make this
// proxied request to "fall through" other existing handlers,
// and whatever mocked response they return will be used here.
return fetch(proxiedRequest)
}),
// Now, describe individual operations to the proxied endpoint.
// This is a much nicer way to provide method + path matching.
http.get('https://placeholder.com/info/foo', () => {
return HttpResponse.json({ ok: true })
}),
http.post('https://placeholder.com/info/bar', async ({ request }) => {
const data = await request.json()
return HttpResponse.json(data, { status: 201 })
}),
] I recommend going with something like this as it gives you more power over request matching while also allowing you to benefit from other MSW features like delays, one-time handlers, etc. Let me know if you have any other questions! |
Beta Was this translation helpful? Give feedback.
Hi, @ellsworthjc. Thank you for your kinds words!
You can choose whichever setup makes sense in the context of your request client, so what you've showcased makes sense if the request body contains the predicate as to how to handle the outgoing requests.
That being said, I feel you can take advantage of MSW's built-in routing if you unfold the requests. Let me show you how.