metosin / ring-swagger

Swagger Spec for Clojure Web Apps
http://metosin.github.io/ring-swagger/doc/
372 stars 83 forks source link

Support openapi3.0 #121

Open ikitommi opened 7 years ago

ikitommi commented 7 years ago

could be a ring.swagger.openapi3 ns, maybe sharing code from ring.swagger.json-schema (version differences via options just like with :in?).

rajcspsg commented 7 months ago

I would like to pick up this issue and work on it

velios commented 2 months ago

This looks to be in its final stages. What can I do to help complete this? This is a very valuable improvement.

frenchy64 commented 2 months ago

@velios I'm getting around to trying it out in practice, @rajcspsg sent me these repl snippets. If you can figure out how to test it, please do.

(require '[schema.core :as s]
         '[ring.swagger.openapi3 :as openapi3]
         '[ring.swagger.openapi3-schema :as openapi-schema]
         '[ring.swagger.swagger2 :as swagger2]
         '[ring.swagger.swagger2-full-schema :as full-schema]
         '[ring.swagger.json-schema :as rsjs]
         '[ring.swagger.extension :as extension]
         '[ring.swagger.validator :as validator]
         '[linked.core :as linked]
         '[ring.util.http-status :as status]
         '[midje.sweet :refer :all])

(require '[plumbing.core :as p])
(require '[ring.swagger.common :as common])
(require '[clojure.string :as str])
(import [java.util Date UUID])
(import [java.util.regex Pattern])
(import [org.joda.time DateTime])
(import [org.joda.time LocalTime])
(import [org.joda.time LocalDate])
(import (java.io File))

(s/defschema Anything {s/Keyword s/Any})
(s/defschema Nothing {})

(s/defschema LegOfPet {:length Long})

(s/defschema Pet {:id Long
                  :name String
                  :leg LegOfPet
                  (s/optional-key :weight) Double})

(s/defschema Parrot {:name String
                     :type {:name String}})

(s/defschema Turtle {:name String
                     :tags  (s/if map? {s/Keyword s/Keyword} [String])})

(s/defschema NotFound {:message s/Str})

(s/defschema Tag
  {(s/optional-key :id) (rsjs/field s/Int {:description "Unique identifier for the tag"})
   (s/optional-key :name) (rsjs/field s/Str {:description "Friendly name for the tag"})})

(def tag-with-meta (with-meta Tag {:examples {:id "abc" :name "New Tag"}}))

(s/defschema FatalError
  {(s/optional-key :error-code) (rsjs/field s/Str {:description "error code for error"})
   (s/optional-key :error-desc) (rsjs/field s/Str {:description "Error description"})})

(def fatal-error-examples {:InvalidExample {:id "invalid123" :description "invalid request" :code "invalid"}})
(s/defschema FatalError {:id String
                  :description String
                  :code String
                  })
(def fatal-error-with-examples (with-meta FatalError {:json-schema fatal-error-examples}))

(openapi3/openapi-json {:paths {"/api" {:post {:requestBody {:content {"application/json" {:foo java.lang.Long}}}
                                                :responses   {200 {:description "ok" :content {"application/json" {:schema Tag}}}
                                                                                    400 {:description "error" :content {"application/xml" {:schema FatalError}}}}}}}})

(openapi3/move-schemas (openapi3/openapi-json {:paths {"/api" {:post {:parameters  {
                                                                                    :query  (merge Anything {:x Long :y Long})
                                                                                    :path   (merge Anything {:a String :b String})
                                                                                    :header (merge Anything {:Content-Type String :Accept String})
                                                                                    }
                                                                      :security    {:bearerAuth {:type "http" :scheme "bearer" :scopes []}}
                                                                      :requestBody {:content {"application/json" {:foo s/Str}}}
                                                                      :responses   {200 {:description "ok" :content {"application/json" {:schema Tag}}}
                                                                                    400 {:description "error" :content {"application/xml" {:schema FatalError}}}}}}}}))

(openapi3/openapi-json {:paths {"/api" {:post {:requestBody {:content {"application/json" {:foo {: bar java.lang.Long}}}}
                                                :responses   {200 {:description "ok" :content {"application/json" {:schema Pet}}}}}}}})