pb33f/libopenapi-validator

Nested object schema validation in query params

hendrikheil opened this issue · 2 comments

Given my understanding of JSON schema and OpenAPI (3.1) the following schema is supposed to be valid:

paths:
  /path:
    get:
      parameters:
        - name: obj
          in: query
          style: deepObject
          schema:
            type: object
            properties:
              root:
                type: string
              nested:
                type: object
                properties:
                  child:
                    type: string
          required: true

Meaning an URL like /path?obj[root]=test1&obj[nested][child]=test2 should pass the validation against the schema above.

As far as I can tell from the code deepObject style query parameters are decoded to a flat map of QueryParam arrays. This works for objects with a depth of one, but won't work for objects with more depth.

Since this type of notation isn't really standardized anywhere, I think the current behavior is generally not wrong.

OpenAPI 3.1 makes no remarks about the level of nesting, where as 3.0 does specify only a single level of nesting.
But in general, there is an ongoing discussion: OAI/OpenAPI-Specification#1706

Since behavior isn't well defined, I think it might still be a good idea to implement the "qs" style of notation, since nested object schemas are generally definable in OAS 3.x.

However, there is a workaround to this issue, which is just flattening the object keys.

paths:
  /path:
    get:
      parameters:
        - name: obj
          in: query
          style: deepObject
          schema:
            type: object
            properties:
              root:
                type: string
              nested[child]:
                type: string
          required: true

I don't think it has the exact same semantics and definitely doesn't allow as fine grained of a control as one would have with using object type schemas, but I think it is decent enough for a lot of cases.

@daveshanley What do you think about this? Worth keeping it open or should this be closed and the behavior stay as is?

I have not spent a huge amount of time here in deeply nested deepObject encoding (it seems like a anti-pattern to me) however I do think there is value is growing support for it, as I have seen this type of design a few times and there is a need to support it.