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

Unexpected reference while generating swagger specs with custom types #739

Open
souenzzo opened this issue Aug 12, 2022 · 5 comments
Open
Labels
enhancement New feature or request

Comments

@souenzzo
Copy link

souenzzo commented Aug 12, 2022

I'm trying to use custom types and customize its swagger spec output.

On this example, I simplified a lot. In my actual code, :my/int is created via malli.core/-simple-schema.

But we can see the unexpected behavior in this code:

(require '[malli.core :as m]
         '[malli.swagger :as ms])
(ms/transform [:map
               [:ok :int]
               [:notok :my/int]]
  {:registry (assoc (m/default-schemas)
               :my/int (m/-simple-schema {:type          :my/int
                                          :pred          int?
                                          :property-pred (m/-min-max-pred nil)}))})
=> {:type        "object",
    :properties  {:ok {:type   "integer"
                       :format "int64"}
                  :notok
                  ;; expected
                  #_{:type "integer", :format "int64"}
                  ;; actual
                  {:$ref "#/definitions/:my/int"}}
    :required    [:ok :notok]
    ;; not expected
    :definitions {:my/int {:type "integer", :format "int64"}}}

I don't want to generate a ref to this type. I just want to put it "in-place"

@pfeodrippe
Copy link

pfeodrippe commented Aug 12, 2022

It seems Malli puts "in-place" only non-qualified keywords, no idea why

(malli.swagger/transform
   (mu/closed-schema
    [:map {:registry {:eita/schema :int}}
     [:a :eita/schema]]))
;; =>
{:type "object",
 :properties {:a {:type "integer", :format "int64"}},
 :required [:a]}


(malli.swagger/transform
   [:map {:registry {:eita/schema :int}}
    [:a :eita/schema]])
;; =>
{:type "object",
 :properties {:a {:$ref "#/definitions/:eita/schema"}},
 :required [:a],
 :definitions #:eita{:schema {:type "integer", :format "int64"}}}

@ikitommi ikitommi added the enhancement New feature or request label Aug 28, 2022
@ikitommi
Copy link
Member

I see. Ideas welcome on how to change this in an elegant way.

@souenzzo
Copy link
Author

More wired behaviors. Still trying to understand the root cause.

(def opts
  {:registry (assoc (m/default-schemas)
               :my/int (m/-simple-schema
                         ;; exactly the same as :int
                         {:type          :my/int
                          :pred          int?
                          :property-pred (m/-min-max-pred nil)}))})
(m/ast :int opts) #_#_=> {:type :int}
(m/ast [:int] opts) #_#_=> {:type :int}
;; wired: m/ast behaves differently between equivalent notations
;; root cause: https://github.com/metosin/malli/blob/0.8.9/src/malli/core.cljc#L1994
;; seems that -reference? function is the problem
(m/ast :my/int opts) #_#_=> {:type :malli.core/schema, :value :my/int}
(m/ast [:my/int] opts) #_#_=> {:type :my/int}

;; transform with kw: not what I expect
(ms/transform :my/int opts) #_#_=> {:$ref "#/definitions/:my/int", :definitions {:my/int {}}}
;; transform with []: wrong
(ms/transform [:my/int] opts) #_#_=> {}

@ikitommi
Copy link
Member

ikitommi commented Sep 3, 2022

Digged into this. I think the bug is actually how the non-qualified types are used, e.g.

(m/form [:schema {:registry {:my-int :int}} :my-int])
; => [:schema {:registry {:my-int :int}} :int]

.. the last child is of type :malli.core/schema but due to malli internals to form will show in inlined value. This is not good as we are losing information. This should be fixed.

Another - how do define qualified keys (or string) that are not reference values, just values. I think a good way would be to change internals so that any value in the registry that is a IntoSchema instance, should not be handled as a reference, just a type instead. This would allow tools like the swagger/openapi transformers not to create references out of those.

@ikitommi
Copy link
Member

ikitommi commented Sep 3, 2022

#749

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

3 participants