Description
I'm fairly new to Clojure, so I could be doing something wrong here, but I was hoping to get some advice on structuring a project.
I'm working on a web API project, and I've split the files up into something like this:
/
|- src/
|- test_api/
|- handler.clj
|- routes/
|- product.clj
The idea is to split the routes that are grouped by context out into their own files; i.e. routes/product.clj
contains the routes for the /products
context.
I've found that the swagger docs for the defroutes*
nested in the context defined in routes/product.clj
don't get generated unless I explicitly :refer
to them in handler.clj
- I'd prefer to only use :require :as
so I can refer to them under their namespaces.
I've included examples of the code below. handler.clj
has some comments showing which version of the :require
statements work, and which version doesn't.
handler.clj
(ns test-api.handler
(:require [compojure.api.sweet :refer :all]
[ring.util.http-response :refer :all]
[schema.core :as s]
;; the line below generates the correct swagger docs
[test-api.routes.product :as productroutes :refer [product-routes get-product-by-id get-products-by-barcode]]
;; the line below doesn't generate the docs for the '/products/:id' or '/products/barcode/:barcode' routes, but
;; docs for 'products/test' will be generated
;;[test-api.routes.product :as productroutes :refer [product-routes]]
))
(s/defschema Result {:result Long})
(defapi app
(swagger-ui)
(swagger-docs
:title "Test-api Api"
:description "this is Test-api Api.")
(swaggered "products"
:description "products api"
productroutes/product-routes)
(swaggered "math"
:description "playing with parameters"
(GET* "/plus" []
:return Result
:query-params [x :- Long, {y :- Long 1}]
:summary "x+y (y default to 1)"
(ok {:result (+ x y)}))))
routes/product.clj
(ns test-api.routes.product
(:require [compojure.api.sweet :refer :all]
[ring.util.http-response :refer :all]
[schema.core :as s]
[test-api.services.product-services :as product-service]
[test-api.data.mockdata :refer [db]]))
(defroutes* get-product-by-id
(GET* "/:id" []
:summary "get a product by id"
:path-params [id :- Long]
(ok (product-service/get-product-by-id db id))))
(defroutes* get-products-by-barcode
(GET* "/barcode/:barcode" []
:summary "get products with matching barcode"
:path-params [barcode :- String]
:query-params [lon :- Double, lat :- Double]
(ok (product-service/find-products-by-barcode-and-location db barcode lon lat))))
(defroutes* product-routes
(context "/products" []
get-product-by-id
get-products-by-barcode
(GET* "/test" []
(ok "test"))
))
Is there a way to get this working without including the routes explicitly?
Thanks in advance for any advice you can give me!