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

Support for OpenAPI3 #84

Closed
ikitommi opened this issue May 14, 2018 · 22 comments · Fixed by #563
Closed

Support for OpenAPI3 #84

ikitommi opened this issue May 14, 2018 · 22 comments · Fixed by #563

Comments

@ikitommi
Copy link
Member

ikitommi commented May 14, 2018

This spans over multiple repos, but can be done in parts.

Schema -> OpenAPI3

Spec -> OpenAPI3

Malli -> OpenAPI3

Reitit Coercion

  • currently, there is only one body-coercion for request and one for response. We should add support for content-type based coercion:

Coercion for all content-types

(require '[reitit.ring :as ring])
(require '[reitit.ring.coercion])
(require '[reitit.coercion.spec])
(require '[muuntaja.middleware])

(ring/ring-handler
  (ring/router
    ["/plus"
     {:get {:parameters {:body {:x int?, :y int?}}
            :responses {200 {:body {:total pos-int?}}}
            :handler (fn [{{{:keys [x y]} :body} :parameters}]
                       {:status 200, :body (+ x y)})}}]
    {:data {:middleware [muuntaja.middleware/wrap-format
                         reitit.ring.coercion/coerce-request-middleware
                         reitit.ring.coercion/coerce-response-middleware]
            :coercion reitit.coercion.spec/coercion}}))

Coercion per content-type

  • new type :content (from OpenAPI3) which allows content-type->model mappings.
  • should be disallowed with Swagger
(ring/ring-handler
  (ring/router
    ["/plus"
     {:get {:parameters {:content {"application/json" {:x neg-int?, :y neg-int?}
                                   "application/edn" {:x pos-int?, :y pos-int?}}}
            :responses {200 {:content {"application/json" {:json int?}
                                       "application/edn" {:edn int?}}}}
            :handler (fn [{{{:keys [x y]} :body} :parameters :as request}]
                       (let [content-type (-> request :muuntaja/response :format)
                             body (case content-type
                                    "application/json" {:json (+ x y)}
                                    "application/edn" {:edn (+ x y)})]
                         {:status 200, :body body}))}}]
    {:data {:middleware [muuntaja.middleware/wrap-format
                         reitit.ring.coercion/coerce-request-middleware
                         reitit.ring.coercion/coerce-response-middleware]
            :coercion reitit.coercion.spec/coercion}}))

... having both :body and :content could be allowed, the :body could be used as a default if the content-type doesn't match.

@ikitommi
Copy link
Member Author

another option for the new key :content would be to reuse the :body key, but I think it would conflict with the string keys.

@valerauko
Copy link
Contributor

There seem to be quite a lot of changes for OpenAPI 3.0. Would all of it need to be implemented here? https://swagger.io/blog/news/whats-new-in-openapi-3-0/

@ikitommi
Copy link
Member Author

I think the core change is for the content-negotiation & better json-schema mappings. The rest (security &) are anyway left for client apps / libs to do as there are no existing helpers in reitit for those.

@ikitommi
Copy link
Member Author

ikitommi commented Jun 8, 2020

I think we could move the swagger parameter mapping from spec-tools and schema-tools into reitit-spec and reitit-schma modules. reitit-malli already does this: only the malli->JSON Schema mappings are in malli repo, and all the parameter handling is done here: https://github.com/metosin/reitit/blob/master/modules/reitit-malli/src/reitit/coercion/malli.cljc

Much easier to develop as it's all under one repo, open even opportunity to share code between the three impls.

@ikitommi
Copy link
Member Author

ikitommi commented Jun 8, 2020

@czan
Copy link

czan commented Aug 10, 2020

In case it helps someone, until this issue is solved I created a hacky conversion from the existing reitit Swagger output to an OpenAPI spec. I first wrote it when I was using Spec coercion, but now I've moved to using Schema, so I'm not as confident about what gets generated from a Spec. I've been quite happy with my generated OpenAPI specs using this.

There are definitely gaps in functionality that I don't need/haven't run into yet, but it's something.

https://gist.github.com/czan/8752cacf527ceb0e64982b9fa8747892

@Koura
Copy link
Contributor

Koura commented Aug 31, 2020

In case it helps someone, until this issue is solved I created a hacky conversion from the existing reitit Swagger output to an OpenAPI spec. I first wrote it when I was using Spec coercion, but now I've moved to using Schema, so I'm not as confident about what gets generated from a Spec. I've been quite happy with my generated OpenAPI specs using this.

There are definitely gaps in functionality that I don't need/haven't run into yet, but it's something.

https://gist.github.com/czan/8752cacf527ceb0e64982b9fa8747892

I'm currently working on this issue and hopefully this can be closed soonish

@danielneal
Copy link

@Koura How far did you get with this?

@Koura
Copy link
Contributor

Koura commented Feb 2, 2021

@danielneal Sorry for the radio silence and slow progress. I haven't really been able to progress this for the last few months but should be able to continue now. Afaik support for schema and specs is already done but haven't yet been taken into use on reitit side. I have a WIP for the malli side of things

@sundbry
Copy link

sundbry commented Feb 13, 2021

Hi all, just jumping in here while trying to get my api integrated with some OpenAPI V3 tools. The gist from @czan works well. I recommend incorporating the following patch which helped me to get my /openapi.json validated.

66,69c65,68
<                 (assoc (dissoc endpoint :produces)
<                        :parameters non-body-parameters
<                        :requestBody fixed-body-parameter
<                        :responses fixed-responses)))
---
>                 (cond-> (dissoc endpoint :produces :consumes)
>                   non-body-parameters (assoc :parameters non-body-parameters)
>                   fixed-body-parameter (assoc :requestBody fixed-body-parameter)
>                   fixed-responses (assoc :responses fixed-responses))))

@hukka
Copy link

hukka commented Oct 8, 2021

@Koura Swagger2 has annoying deficiencies like missing support for anyOf, so even a WIP would be interesting to see, and possibly to continue from.

@hukka
Copy link

hukka commented Oct 9, 2021

OpenAPI 3.1 claims to be 100% compatible with JSONSchema, which already has support in, for example, Malli. Perhaps it would be feasible to skip 3.0 and go straight to the newest version, even if the ecosystem hasn't for most parts migrated to it (based on https://openapi.tools/).

@piotr-yuxuan
Copy link
Contributor

+1 🙂

@piotr-yuxuan
Copy link
Contributor

piotr-yuxuan commented Mar 15, 2022

Thank you so much @ikitommi and @Koura for all the open-source marvels to which you've contributed! I'd really be interested in having the latest version of OpenAPI (3.0, 3.1, 3.x?) supported by malli. Off the top of my head here are the features of OpenAPI (3.x) that I miss in Swagger (2.0):

  • Authentication schemes like bearer and OpenID (not related to reitit as @ikitommi mentionned above)
  • Response links
  • Different example values for different content mimetype

If somehow you had enough free brain time to dump a list of tasks yet to be completed so as to move toward all reitit coercions supporting OpenAPI, I think it might be helpful for the wider community to try and contribute – happy to look at it and see what I can do 🙂

@bowbahdoe
Copy link

This would be really cool for integration with stoplight - it takes swagger but its not happy with it

@jasonjckn
Copy link

+1 need this feature as well.

@souenzzo souenzzo mentioned this issue Sep 5, 2022
5 tasks
@grzm
Copy link

grzm commented Jan 19, 2023

What's the current status of this work? I may be willing to throw some cycles at it. Having support for OpenApi 3.x would really be nice.

@PavlosMelissinos
Copy link

What's the current status of this work?

@grzm Afaik, there's this open PR that requires review.

I may be willing to throw some cycles at it.

Until metosin can review it, if you can spare some time I think it might be nice to test it in an actual project and report any problems (I've been meaning to do that for a while...).

@opqdonut
Copy link
Member

opqdonut commented Mar 1, 2023

FYI I'm working on this at metosin, trying to get all the various contributions glued together and adding the missing pieces.

@opqdonut opqdonut moved this to 👍 Backlog in Metosin Open Source Backlog Mar 7, 2023
@opqdonut opqdonut moved this from 👍 Backlog to 🏗 Doing in Metosin Open Source Backlog Mar 7, 2023
@opqdonut opqdonut self-assigned this Mar 7, 2023
@github-project-automation github-project-automation bot moved this from 🏗 Doing to ✅ Done in Metosin Open Source Backlog Mar 15, 2023
@opqdonut
Copy link
Member

opqdonut commented Mar 15, 2023

Initial support for OpenAPI3 schemas is now in master and will be out in the next release.

Done:

TODO:

This was referenced Mar 15, 2023
@opqdonut
Copy link
Member

One more thing: #605

@opqdonut
Copy link
Member

opqdonut commented May 3, 2023

OpenAPI3 support is now out in 0.7.0-alpha1. Blog post here: https://www.metosin.fi/blog/openapi3/

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

Successfully merging a pull request may close this issue.