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

Allow multiple marshal_with decorators #347

Open
MajorDallas opened this issue Jul 1, 2021 · 4 comments
Open

Allow multiple marshal_with decorators #347

MajorDallas opened this issue Jul 1, 2021 · 4 comments
Labels
enhancement New feature or request

Comments

@MajorDallas
Copy link

Is your feature request related to a problem? Please describe.
Using @namespace.marshal_with multiple times on one method results in only the outer-most marhal_with's model being used. The only workaround is to instead use @namespace.response and explicitly call marshal within a mess of control flow statements.

Describe the solution you'd like
I would like to get rid of the many if-blocks and replace them with marshal_with decorators that can dispatch to the correct model based on status code.

# instead of this:
    @ns.response(200, ok_model)
    @ns.response(400, validation_err)
    @ns.response(500, internal_err)
    def post(self):
        result = do_stuff_on(request.json)
        if (status := result[1]) == 200:
            return marshal(result.content, ok_model), result[1]
        elif status == 500:
            return marshal(result.content, internal_err), result[1]
        elif status == 400:
            return marshal(result.content, validation_err), result[1]
        # This gets REAL messy if you can get any of a dozen different outcomes that all need 
        # distinct models, or if the result state is communicated in a more rich/complex way 
        # or not at all.

# this:
    @ns.marshal_with(ok_model, code=200)
    @ns.marshal_with(validation_err, code=400)
    @ns.marsnal_with(internal_err, code=500)
    def post(self):
        return do_stuff_on(request.json)

# or even this:
    @ns.marshal_with({200: ok_model, 400: validation_err, 500: internal_err})
    def post(self):
        return do_stuff_on(request.json)

I don't think the current closure-based approach can be easily hacked to allow this. My first thought was to use a mapping of model names to marshalling.marshal_with instances, but I'm not sure how to change what the closure returns or how the handler then gets called. Second thought was singledispatch, but since that can't dispatch on Literal types as of Py38 you'd need a class for every HTTP status code... (or a class factory).

@MajorDallas MajorDallas added the enhancement New feature or request label Jul 1, 2021
@Enno-H
Copy link

Enno-H commented Jul 26, 2021

We definitely need this feature.

@yanivakiva
Copy link

this is a MUST feature

@mhetreramesh
Copy link

Is there any solution or workaround to this in 2023?

@nick4fake
Copy link

So basically the most trivial example is not supported? We can't use marshal when there are multiple possible http codes, so... always?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

5 participants