metosin / reitit

A fast data-driven routing library for Clojure/Script
https://cljdoc.org/d/metosin/reitit/
Eclipse Public License 1.0
1.43k stars 257 forks source link

Swagger -> Reitit conversion #272

Open ikitommi opened 5 years ago

ikitommi commented 5 years ago

A tool that reads swagger json/yaml and emits a reitit template. Some pointers:

ikitommi commented 5 years ago

quick & dirty sample:

(require '[jsonista.core :as j])

(-> "https://petstore.swagger.io/v2/swagger.json"
    (slurp)
    (j/read-value (j/object-mapper {:decode-key-fn true}))
    :paths
    (->> (map (fn [[k v]]
                [(subs (str k) 1)
                 (->> v
                      (map (fn [[k v]]
                             [k (select-keys v [:description :summary])]))
                      (into {}))]))
         (into {})))
;{"/pet/{petId}/uploadImage" {:post {:description "", :summary "uploads an image"}},
; "/store/order" {:post {:description "", :summary "Place an order for a pet"}},
; "/user/logout" {:get {:description "", :summary "Logs out current logged in user session"}},
; "/store/inventory" {:get {:description "Returns a map of status codes to quantities",
;                           :summary "Returns pet inventories by status"}},
; "/user/createWithList" {:post {:description "", :summary "Creates list of users with given input array"}},
; "/user/{username}" {:get {:description "", :summary "Get user by user name"},
;                     :delete {:description "This can only be done by the logged in user.", :summary "Delete user"},
;                     :put {:description "This can only be done by the logged in user.", :summary "Updated user"}},
; "/user/createWithArray" {:post {:description "", :summary "Creates list of users with given input array"}},
; "/pet/{petId}" {:get {:description "Returns a single pet", :summary "Find pet by ID"},
;                 :delete {:description "", :summary "Deletes a pet"},
;                 :post {:description "", :summary "Updates a pet in the store with form data"}},
; "/pet/findByStatus" {:get {:description "Multiple status values can be provided with comma separated strings",
;                            :summary "Finds Pets by status"}},
; "/pet/findByTags" {:get {:description "Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.",
;                          :summary "Finds Pets by tags"}},
; "/pet" {:post {:description "", :summary "Add a new pet to the store"},
;         :put {:description "", :summary "Update an existing pet"}},
; "/user/login" {:get {:description "", :summary "Logs user into the system"}},
; "/user" {:post {:description "This can only be done by the logged in user.", :summary "Create user"}},
; "/store/order/{orderId}" {:get {:description "For valid response try integer IDs with value >= 1 and <= 10. Other values will generated exceptions",
;                                 :summary "Find purchase order by ID"},
;                           :delete {:description "For valid response try integer IDs with positive integer value. Negative or non-integer values will generate API errors",
;                                    :summary "Delete purchase order by ID"}}}
wandersoncferreira commented 4 years ago

@ikitommi I did not get the context where this feature would be relevant to reitit yet. Can you share some use-cases for this?

It's not clear the level of detail that we should provide in such translations. While performing a first draft for this I manage to create the ["/swagger.json".. endpoint and enrich the other paths with informations such as produces, consumes but some questions are:

  1. Would be relevant to include some libraries that is required, for example, handler: (swagger/create-swagger-handler) for the "swagger.json" endpoint or even the necessary middlewares to produces/consumes correctly.

  2. Tags?

  3. I think it's not possible today to parse correctly the "spec" definitions and do something useful with it.

  4. This tool would be a new dependency library/module of reitit or something to be added to reitit-swagger existing module?

Thanks o/