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

OpenAPI 3 parameter documentation not generated for :and #705

Open
Sardtok opened this issue Oct 29, 2024 · 4 comments
Open

OpenAPI 3 parameter documentation not generated for :and #705

Sardtok opened this issue Oct 29, 2024 · 4 comments

Comments

@Sardtok
Copy link

Sardtok commented Oct 29, 2024

With the older OpenAPI 2 support I could define parameters to have top-level validation like so:

:parameters {:query [:and [:map
                           [:x int?]
                           [:y int?]]
                     [:fn #(< (:x %) (:y %))]]}

The parameters would show up in the generated JSON and in Swagger UI. When I change to create-openapi-handler, the parameter list for the endpoint is empty.

Is this by design? Do I need to move this kind of validation out of the Malli coercion flow?

@opqdonut
Copy link
Member

The problem is that the :query parameter schema should be a :map so that the OpenAPI generation can grab the schemas of the individual query params out of it. In the final OpenAPI spec, the :map level disappears, in a sense, and the spec only mentions the individual properties.

We should probably add a warning for the case when the OpenAPI generation fails to find the individual query params.

We could also add special case support for [:and [:map ...] [:fn ...]], but handling something like [:and [:map ...] [:map ...]] would be more tricky, so I'm hesitant to do that.

The reason this works in Swagger/OpenAPI2 is that the version of :and in Swagger, "x-allOf" is a hack, and the final schema looks more like a map schema. See below.

;; Input
[:and
 [:map [:x int?] [:y int?]]
 [:fn #(< (:x %) (:y %))]]
;; OpenAPI 2 output
{:properties {:x {:format "int64", :type "integer"}, :y {:format "int64", :type "integer"}},
 :required [:x :y],
 :type "object",
 :x-allOf [{:properties {:x {:format "int64", :type "integer"},
                         :y {:format "int64", :type "integer"}},
            :required [:x :y],
            :type "object"}
           {}]}
;; OpenAPI 3 output
{:allOf [{:properties {:x {:type "integer"}, :y {:type "integer"}},
          :required [:x :y],
          :type "object"}
         {}]}

@opqdonut
Copy link
Member

I've added a warning for this.

@Sardtok
Copy link
Author

Sardtok commented Oct 30, 2024

I can see how supporting every possible permutation of a schema that is valid for coercion would be tricky. I would imagine [:and [:map ...] [:map ...]] would be a map union of the two maps, but I can see how collisions between keys could be a problem. During coercion, you can simply apply the rules, even if rules conflict, but generating an OpenAPI spec from such a schema wouldn't be possible.

E.g. this shouldn't be a problem:

[:and [:map [:x :int]]
      [:map [:y :int]]

But something like the following doesn't make sense, and would be impossible to generate a spec from:

[:and [:map [:x :int]]
      [:map [:x :string]]

And then there's of course a question of whether :or could be supported. I don't think we have any cases of :or for query parameter specs, but I think there are cases that could make sense, but it would be very difficult to say anything about parameters being required or not.

@opqdonut
Copy link
Member

opqdonut commented Oct 30, 2024

Yeah the core problem here is that OpenAPI wants to model each query parameter separately, so there's really no way to even express something like [:or [:map [:x :int]] [:map [:y :string]]] in OpenAPI 3. You just have to go with a more open schema like [:map [:x {:optional true} :int] [:y {:optional true} :string]].

PS. this is for query params. For body params, :or, :and, :multi etc. work perfectly!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: 🇰‍🇼 Waiting
Development

No branches or pull requests

2 participants