-
-
Notifications
You must be signed in to change notification settings - Fork 517
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
feat(HttpResponse): add empty response helper for strict empty responses #1807
Conversation
Hi, @christoph-fricke 👋 That's for raising this. // Typing the body with "never" does not allow any response...
http.delete<never, never, never>('/resource', () => {
return new HttpResponse(); // Errors
}); This looks more like a bug to me. This should compile. Maybe we can try looking into why I can't say I like the idea of I want to be extremely cautious with the Can you share what exact TypeScript error you get when using the |
I was briefly looking at this, and figured some sample errors help
Some sample errors here: |
@mattcosta7 Thank you for providing these sample errors! I have been out of town for the past two days and didn't have my laptop on me. Using
|
I think FWIW
this appears related to this type: msw/src/core/handlers/RequestHandler.ts Lines 30 to 35 in 88c45ea
Which could be extended to account for null as well as undefined, but probably not never? |
each of these works fine as an empty response, since they'll accept a valid |
I think we have two separate topics here. First one being Regarding I am way more interested in strictly-typed empty responses, which this PR is all about:
I am approaching this topic from the angle of Openapi-MSW. I want to express that a handler can only return responses with empty content as OpenAPI-MSW is all about surfacing type conflicts in MSW resolvers when they no longer match their OpenAPI specification, e.g. return a response body that does not match the defined response schema. Imagine an API endpoint that returns some response content and is now changed to return no-content with the response. This should surface a type error in MSW handlers for this endpoint since they would still return a response and have to be adjusted. And indeed, this scenario does surface a type error when the response body generic of the MSW resolver function gets typed with However, I don't thing the current way of creating strictly typed responses with no content ( I hope that the OpenAPI scenario better explains what I am trying to achieve and why. I created a small Playground that hopefully helps explaining it even more: Link to Playground |
Thanks for the detailed discussion, @christoph-fricke, @mattcosta7! Will provide my input below. On default body typesThe msw/src/core/handlers/RequestHandler.ts Lines 13 to 20 in 88c45ea
The difference is like what you'd expect:
JavaScript is a bit not in our favor here because runtime has no distinction between new Response().body
// null
new Response(undefined).body
// null
new Response(null).body
// null
On
|
Actually, my bad, I'm always forgetting about this TS hack to know if a generic was provided: type X<T> = [T] extends [never] ? 'NOT PROVIDED' : 'PROVIDED' Alas, we cannot use this for
🫠 |
@kettanaito Thank you for your input! I will have a look at this again this weekend and convert the PR from
I think this is only partially true, right? You are right that in a client/server setting, with both specifying the same request- and response-body for a communication, they can't rely on the incoming data matching the specified type. Meaning, the client can't rely on it's response body type and the server cannot rely on the request body type. However, for the client the request body is a contract that must be fulfilled by its requests, and for the server the response body type is a contract that must be fulfilled by its response. They can make sure that the type of the data they own is matched. When both rely on the same contract types, they can make sure that they at least fulfill their own bargain to make the communication work.
Reflecting this back onto MSW handlers: The request body type is kinda a lie that we have for convenience. But the response body type is able to act as a contract that resolvers have to fulfill to ensure that they return a response that is expected by the application (client). Of course, this doesn't matter if the real backend returns completely different responses, but this is where OpenAPI comes into play to specify a communication contract. ;) |
The recent changes about a proper response body type validation can help us implement this (#2107). In fact, I can achieve this behavior that validates the empty ( My only comment would be that it'd be nice if that type error happened on the argument to Edit: I think I know the difference that causes it. |
I've opened a pull request that will add support for explicit empty response bodies by using @christoph-fricke, could you please take a look at that pull request and confirm that it satisfies your use cases? Thanks. |
I will close this in favor of #2118. It achieves the original use case without having to resort to custom response static methods. Thanks for raising this, @christoph-fricke! I can still use your wise eyes on that pull request. |
This PR adds a helper that makes it possible to create a
StrictResponse<null>
response without a content header or type casting.Motivation
We have some scenarios where handlers return responses without a body. This appears to be best enforced by typing the response body for resolver functions with
null
.However, as you can see in the example, creating a response that satisfies the resolver either also sets a content-type or requires casting. Neither of these downsides should be required to create an empty response. Therefore, this PR adds
HttpResponse.empty
to work around this downsides, which also sets the default status to 204 as a little bonus.If you agree on adding this to MSW, I can create the relevant PR for updating the documentation for
HttpResponse.empty
.