Cornices/cornice

Question: Ambiguity regarding multi-validator use case with colander

Opened this issue · 1 comments

When using

class SomeSchema(colander.MappingSchema):
    path = ...
    header = ...
    querystring = ...

some_service = cornice.Service(...)

@some_service.get(validators=colander_validator, schema=SomeSchema())
def some_view(request): ...

Everything seems to work as expected.

However, when using multiple colander-based validators simultaneously (i.e.: validators=[colander_path_validator, colander_querystring_validator, colander_header_validator], I get some weird behavior where each validator seems to consider that specified schema is only representing their own sub-location rather than the full "request" as in the case of colander_validator, leading to response errors:

{
  "status": "error",
  "errors": [
    {
      "location": "path",
      "name": "path",
      "description": "Missing value for required field without any default."
    },
    {
      "location": "path",
      "name": "header",
      "description": "Missing value for required field without any default."
    },
    {
      "location": "path",
      "name": "querystring",
      "description": "Missing value for required field without any default."
    },
    {
      "location": "path",
      "name": "path",
      "description": "Missing value for required field without any default."
    },
    {
      "location": "path",
      "name": "header",
      "description": "Missing value for required field without any default."
    },
    {
      "location": "path",
      "name": "querystring",
      "description": "Missing value for required field without any default."
    }
  ]
}

My specific use case is that I have a single view that can handle 2 distinct content-type simultaneously. Therefore, it is decorated with distinct schema references for the corresponding content-type representation, but I must explicitly ignore the "headers" validator, otherwise both fail against the opposite definition (not sure why they are not handled automatically by the appropriate renderer and/or accept, but maybe this another issue...). Anyway, this leads to a definition similar to the following:

@sd.some_service.get(
    schema=SomeSchemaHTML(),
    accept="text/html",
    validators=[colander_path_validator, colander_querystring_validator],
    renderer="templates/some.mako",
    response_schemas={"200": HTMLReponse()},
)
@sd.some_service.get(
    schema=SomeSchemaJSON(),
    accept="application/json",
    validators=[colander_path_validator, colander_querystring_validator],
    renderer="json",
    response_schemas={"200": JSONReponse()},
)
def some_view(request): ...

Is the above the correct use? So far, I have used multi-decorator service/views for a while (to support redirects or otherwise "compatible" URI for similar contents), and they seemed to work correctly and as intended.
My only recent addition is the validators, and I would like to know if the list approach is valid.
It seems listing validators is supported after looking at the code, but maybe the use of multiple colander_[...]_validator is not supported?
What would be the alternative?

@leplatrem
Would like to get your insights about this. I don't think anyone else can guide me better than you. Thanks in advance!