luminus-framework/luminus

Can't get Swagger UI service endpoints

nenadmitrovic opened this issue · 2 comments

I am trying to access my Swagger service endpoints. Here is the code:

(defn service-routes []
  ["/api"
   {:middleware [middleware/wrap-formats]
    :swagger {:id ::api}}
   ["" {:no-doc true}
    ["/swagger.json"
     {:get (swagger/create-swagger-handler)}]
    ["/swagger-ui*"
     {:get (swagger-ui/create-swagger-ui-handler
             {:url "api/swagger.json"})}]]
   ["/business-partners"
    {:get
     (fn [_]
       (response/ok (bp/business-partners-list)))}]
   ["/business-partner"
    {:post
     (fn [{:keys [params]}]
       (try
         (bp/save-business-partner params)
         (response/ok {:status :ok})
         (catch Exception e
           (let [{id :business-partners/error-id
                  errors :errors} (ex-data e)]
             (case id
               :validation
               (response/bad-request {:errors errors})
               (response/internal-server-error
                 {:errors {:server-error ["Failed to save message!"]}}))))))}]])

Here is my project.clj:

(defproject businesspartners "0.1.0-SNAPSHOT"

  :description "FIXME: write description"
  :url "http://example.com/FIXME"

  :dependencies [[ch.qos.logback/logback-classic "1.2.3"]
                 [cheshire "5.9.0"]
                 [clojure.java-time "0.3.2"]
                 [cprop "0.1.15"]
                 [expound "0.8.3"]
                 [funcool/struct "1.4.0"]
                 [luminus-http-kit "0.1.6"]
                 [luminus-transit "0.1.2"]
                 [luminus/ring-ttl-session "0.3.3"]
                 [markdown-clj "1.10.1"]
                 [metosin/muuntaja "0.6.6"]
                 [metosin/reitit "0.4.2"]
                 [metosin/ring-http-response "0.9.1"]
                 [mount "0.1.16"]
                 [nrepl "0.6.0"]
                 [org.clojure/clojure "1.10.1"]
                 [org.clojure/tools.cli "0.4.2"]
                 [org.clojure/tools.logging "0.5.0"]
                 [org.clojure/clojurescript "1.10.238" :scope "provided"]
                 [org.webjars.npm/bulma "0.8.0"]
                 [org.webjars.npm/material-icons "0.3.1"]
                 [org.webjars/webjars-locator "0.38"]
                 [ring-webjars "0.2.0"]
                 [ring/ring-core "1.8.0"]
                 [ring/ring-defaults "0.3.2"]
                 [selmer "1.12.18"]
                 [com.novemberain/monger "3.1.0"]
                 [reagent "0.10.0"]
                 [cljs-ajax "0.7.3"]
                 [re-frame "0.12.0"]]

  :min-lein-version "2.0.0"
  
  :source-paths ["src/clj" "src/cljc"]
  :test-paths ["test/clj"]
  :resource-paths ["resources" "target/cljsbuild"]
  :target-path "target/%s/"
  :main ^:skip-aot businesspartners.core

  :plugins [[lein-cljsbuild "1.1.7"]]

  :cljsbuild
  {:builds
   {:app {:source-paths ["src/cljs" "src/cljc"]
          :compiler {:output-to "target/cljsbuild/public/js/app.js"
                     :output-dir "target/cljsbuild/public/js/out"
                     :main "businesspartners.core"
                     :asset-path "/js/out"
                     :optimizations :none
                     :source-map true
                     :pretty-print true}}}}
  :clean-targets
  ^{:protect false}
  [:target-path
   [:cljsbuild :builds :app :compiler :output-dir]
   [:cljsbuild :builds :app :compiler :output-to]]

  :profiles
  {:uberjar {:omit-source true
             :aot :all
             :uberjar-name "businesspartners.jar"
             :source-paths ["env/prod/clj"]
             :resource-paths ["env/prod/resources"]}

   :dev           [:project/dev :profiles/dev]
   :test          [:project/dev :project/test :profiles/test]

   :project/dev  {:jvm-opts ["-Dconf=dev-config.edn"]
                  :dependencies [[pjstadig/humane-test-output "0.10.0"]
                                 [prone "2019-07-08"]
                                 [ring/ring-devel "1.8.0"]
                                 [ring/ring-mock "0.4.0"]]
                  :plugins      [[com.jakemccrary/lein-test-refresh "0.24.1"]
                                 [jonase/eastwood "0.3.5"]]
                  
                  :source-paths ["env/dev/clj"]
                  :resource-paths ["env/dev/resources"]
                  :repl-options {:init-ns user}
                  :injections [(require 'pjstadig.humane-test-output)
                               (pjstadig.humane-test-output/activate!)]}
   :project/test {:jvm-opts ["-Dconf=test-config.edn"]
                  :resource-paths ["env/test/resources"]}
   :profiles/dev {}
   :profiles/test {}})

But when I tried to access http://localhost:3000/api/swagger.json in browser I got this response:

{"swagger":"2.0",
 "x-id":["businesspartners.routes.services/api"],
 "paths":{
   "/api/business-partners": {"get":  {}},
   "/api/business-partner":  {"post": {}}}}

I can't figure out why did I get this in json format and why not see Swagger UI to visaulize and interact with my services? I expect to see something like this: https://ibb.co/TYNT6SG

It looks like you're looking for params in the wrong spot here (fn [{:keys [params]}] ...). If you're sending parameters as a body of the request via POST, then you'd need to do (fn [{{params :body} :parameters}] ...) instead. You also need to let Reitit know what the parameters are for it to be able to generate the Swagger UI. This is done by specifying the :parameters key, e.g:

{:parameters {:body {:x int?, :y int?}}
 :responses {200 {:body {:total int?}}}
 :handler (fn [{{params :body} :parameters}] ...)}}

I recommend looking at the docs here for more info.

Ok. Thank you very much. I will check the docs too.