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

Enhancement: Support Multiple Media Types for a single endpoint as in the OpenAPI specification #3882

Open
iongion opened this issue Nov 29, 2024 · 0 comments
Labels
Enhancement This is a new feature or request

Comments

@iongion
Copy link

iongion commented Nov 29, 2024

Summary

OpenAPI already supports these kind of definitions https://swagger.io/docs/specification/v3_0/media-types/#multiple-media-types

Currently, the only way to support this functionality is to duplicated endpoints (paths/methods)

Basic Example

This is how it could work

from litestar import MediaType, get


@get("/resources", media_types=[MediaType.JSON, MediaType.MessagePack])
def retrieve_resource():
    return {"k1":"v1"}

The only way it can currently work is to be redundant, what if one wants the entire api to support multiple media types, would we need to replicate all endpoints like this ? (yes, in current state)

from litestar import MediaType, get


@get("/resources-text", media_type=MediaType.TEXT)
def retrieve_resource_text() -> str:
    return {"k1":"v1"}


@get("/resources-msgpack", media_type=MediaType.MessagePack)
def retrieve_resource_msgpack() -> str:
    return {"k1":"v1"}

Drawbacks and Impact

There is no drawback to this, one could either introduce a new media_types attribute or allow current media_type to also be a list.

Unresolved questions

Ability to globally specify default media_types that then all endpoints that don't override it, will inherit it and avoid being redundant.

Examples from "others"

How "others" do it is to expose a way to support multiple & custom media types by introducing custom request writers and readers. The idea of a body writer / reader is great. What it could bring as benefits:

  • ability to register custom media types with their own validation, serialization, deserialization
  • ability to support multiple media types simultaneously

In .NET a similar pattern is used with body reader/writer and input/output formats and https://learn.microsoft.com/en-us/aspnet/core/web-api/advanced/custom-formatters?view=aspnetcore-9.0

Once registered, an endpoint can harness custom media type in a very elegant way:

    [HttpPost]
    [Route("test")]
    [Produces("application/json", "application/xml", "applicaton/bson", "application/x-msgpack")]
    [Consumes("application/json", "application/xml", "applicaton/bson", "application/x-msgpack")]
    public async Task<IActionResult> TestWebhook([FromBody] MyCustomPayload payload)
    {
        return Ok(await ProcessInput(payload));
    }

The Produces / Consumes decorators(attributes in C#) can applied at class level or at method level in controllers, which also solves the problem of having input/ouput formats registered globally, not only at a method level.

See discussion https://github.com/orgs/litestar-org/discussions/3330


Note

While we are open for sponsoring on GitHub Sponsors and
OpenCollective, we also utilize Polar.sh to engage in pledge-based sponsorship.

Check out all issues funded or available for funding on our Polar.sh dashboard

  • If you would like to see an issue prioritized, make a pledge towards it!
  • We receive the pledge once the issue is completed & verified
  • This, along with engagement in the community, helps us know which features are a priority to our users.
Fund with Polar
@iongion iongion added the Enhancement This is a new feature or request label Nov 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Enhancement This is a new feature or request
Projects
None yet
Development

No branches or pull requests

1 participant