marshmallow-code/flask-smorest

What's the best way to handle multiple routes per function?

Closed this issue · 1 comments

Flask supports multiple endpoints for the same function, for example:

@app.route("/foo")
@app.route("/bar")
def endpoint():
    ...

Attempting the following:

class PetQuery(Schema):
    name = fields.Str()

@bp1.route("/foo", methods=["GET"])
@bp1.arguments(PetQuery(), location="query")
@bp2.route("/bar", methods=["GET"])
@bp2.arguments(PetQuery(), location="query")
def endpoint(*args, **kwargs):
    ...

Will fail with an error similar to:

flask_smorest/blueprint.py:277: in register_views_in_doc
    spec.path(rule=rule, operations=doc, parameters=endpoint_parameters)
apispec/core.py:538: in path
    self._clean_operations(operations)
apispec/core.py:615: in _clean_operations
    operation["parameters"] = self._clean_parameters(
 
               if unique_key in seen:
>               raise DuplicateParameterError(
                    "Duplicate parameter with name {} and location {}".format(
                        parameter["name"], parameter["in"]
                    )
                )
               apispec.exceptions.DuplicateParameterError: Duplicate parameter with name q and location query

It seems that all endpoints associated with the same HTTP method for a function have their parameters combined. Is there a common approach for working around this issue?

Seems like this is related to some previous discussions

This use case is uncommon.

def endpoint(*args, **kwargs):
    ...


endpoint_foo = bp1.route("/foo", methods=["GET"])(bp1.arguments(PetQuery(), location="query")(endpoint))
endpoint_bar = bp2.route("/bar", methods=["GET"])(bp2.arguments(PetQuery(), location="query")(endpoint))

Not so nice visually but this is supposed to work.