Skip to content

Support setting HTTP response headers using some Results methods for Minimal APIs #39585

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

Open
1 task done
martincostello opened this issue Jan 17, 2022 · 3 comments
Open
1 task done
Labels
area-minimal Includes minimal APIs, endpoint filters, parameter binding, request delegate generator etc
Milestone

Comments

@martincostello
Copy link
Member

martincostello commented Jan 17, 2022

Is there an existing issue for this?

  • I have searched the existing issues

Is your feature request related to a problem? Please describe the problem.

Using Minimal APIs with the built-in Results class' methods allows for lots of built-in functionality to perform lots of operations a developer may wish to achieve with an HTTP endpoint, but the experience isn't as good as soon as you need to set an HTTP response header.

In this scenario you're left with at least three possible choices:

  1. Mix and match use of Results with the HttpResponse so you can manually set any headers in the endpoint before returning the IResult.
  2. Use IResultExtensions and a custom IResult implementation to write the body and any headers, likely duplicating implementation details from the internal IResult implementations.
  3. Stop using the Results class and write to the content and headers to the HttpResponse directly in the endpoint.

As an example, take an endpoint which wishes to return an HTTP 429 problem if it wishes to rate limit the client and return a Retry-After response header. The Results.Problem() can be used to return the body and set the status code, but there is no way to set the Retry-After header directly.

To achieve the desired result, you need to either mix-and-match the lower-level HttpResponse usage in the endpoint (and potentially add an extra parameter to access it) with the Results class, write a custom extension, or not use Results at all.

The code would be simpler for the developer in non-advanced cases if they could pass through a simple key-value pair of strings through the Results methods to set HTTP response headers without having to add additional complexity and/or concepts, reducing the "minimalness".

Describe the solution you'd like

Some possible solutions to this (assuming it's not do nothing as this is considered an advanced use case) could include:

  1. Add a new overload or add another optional parameter to methods such as Results.Json() and Results.Problem() that accepts additional headers to set as an IDictionary<string, string>, which would then be passed through to the internals of ObjectResult for use in the ConfigureResponseHeaders(HttpContext) method.
  2. Make the IResult implementations public so behaviours could be easily overridden to extend them. For the HTTP 429 example, a developer could sub-class ObjectResult.ConfigureResponseHeaders(HttpContext) to set the additional header(s) (see also Make IResult methods more testable #37502)

Additional context

No response

@TanayParikh TanayParikh added the old-area-web-frameworks-do-not-use *DEPRECATED* This label is deprecated in favor of the area-mvc and area-minimal labels label Jan 17, 2022
@rafikiassumani-msft rafikiassumani-msft added this to the Backlog milestone Jan 18, 2022
@ghost
Copy link

ghost commented Jan 18, 2022

We've moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time. To learn more about our issue management process and to have better expectation regarding different types of issues you can read our Triage Process.

@davidfowl
Copy link
Member

Add a new overload or add another optional parameter to methods such as Results.Json() and Results.Problem() that accepts additional headers to set as an IDictionary<string, string>, which would then be passed through to the internals of ObjectResult for use in the ConfigureResponseHeaders(HttpContext) method.

Maybe 3. Action<IHeaderDictionary>?

Results.Json(product, headers => headers["Retry-After"] = ...)

@martincostello
Copy link
Member Author

I also like that idea, then you wouldn't need to allocate a dictionary just to set a header.

@captainsafia captainsafia added area-minimal Includes minimal APIs, endpoint filters, parameter binding, request delegate generator etc and removed old-area-web-frameworks-do-not-use *DEPRECATED* This label is deprecated in favor of the area-mvc and area-minimal labels labels Jun 20, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-minimal Includes minimal APIs, endpoint filters, parameter binding, request delegate generator etc
Projects
None yet
Development

No branches or pull requests

5 participants