我正在使用 swagger 为数据库访问程序提供 API。在开发过程中,我通常运行 2 个版本,即我在登录时自动启动的开发版本和生产版本。我想在大张旗鼓的首页上显示一个不同的标题,这样我就不会意外地破坏我的实时数据库。到目前为止,我一直在 swagger 设置中手动编辑标题字段,但这很容易出错,我经常在运行lein uberjar
构建 prod 版本之前忘记更改它。
环境设置似乎是一种理想的方式来做到这一点。luminus lein 模板已经使用了一个从 dev 和 prod 配置文件构建的环境映射,它工作正常,允许我为 2 个构建自动指定不同的端口。我在其中添加了一个条目,它给了我一个在 prod 和 dev 版本中不同的标题。我可以从 repl 中看到它,但是将它包含在 swagger 规范中只会给出null
.
这是我的 photo-api.routes.services.clj 文件开头的 :swagger 定义:
(ns photo-api.routes.services
(:require [cheshire.core :as json]
[compojure.api.sweet :refer :all]
[image-lib.images :as ilim]
[image-lib.preferences :as ilpf]
[image-lib.projects :as ilpr]
[image-lib.write :as ilwr]
[photo-api.db.core :as db]
[photo-api.config :refer [env]]
[photo-api.routes.helpers.build :as build]
[photo-api.routes.helpers.keywords :as keywords]
[photo-api.routes.helpers.open :as open]
[photo-api.routes.helpers.photos :as photos]
[photo-api.routes.helpers.projects :as projects]
[ring.util.codec :refer [url-decode]]
[ring.util.http-response :refer [ok]]
[schema.core :as s]
[clojure.string :as str]))
(defapi service-routes
{:swagger {:ui "/swagger-ui"
:spec "/swagger.json"
:data
{:info
{:version "1.0.1"
;; Switch to correct title before lein uberjar
;; TODO Automate this so swagger page always shows dev or prod version
;;:title "Photo API"
:title (:title env)
:description "Access a mongo database containing details of photos"}}}}
注释掉的 :title 规范工作正常,但(:title env)
调用没有,尽管它与我可以从 repl 成功使用的调用完全相同。我相信环境图是作为 photo-api.config 的一部分构建的,并且从我启动服务器时的启动消息来看,它看起来像是在 http-server 之前成功启动的:
{:started
["#'photo-api.config/env"
"#'photo-api.db.core/db*"
"#'photo-api.db.core/db"
"#'photo-api.handler/init-app"
"#'photo-api.handler/app"
"#'photo-api.core/http-server"]}
user>
这是 photo-api.config,与 luminus 默认值相同:
(ns photo-api.config
(:require [cprop.core :refer [load-config]]
[cprop.source :as source]
[mount.core :refer [args defstate]]))
(defstate env :start (load-config
:merge
[(args)
(source/from-system-props)
(source/from-env)]))
和 dev config.edn 文件:
{:title "**** Photos Development API ****"
:dev true
:port 31999
;; when :nrepl-port is set the application starts the nREPL server on load
:nrepl-port 57251}
我在这里遗漏了一些明显的东西吗?是否需要另一个步骤才能使 env 地图对 swagger 设置可见?
编辑:将调用从更改(:title env)
为 (env :title) 会导致 cider-jack-in 失败,并出现很长的错误消息/堆栈跟踪,其中包括:
Caused by: java.lang.ClassCastException: mount.core.DerefableState cannot be cast to clojure.lang.IFn
再次将其更改为(@env :title)
then 会给出类似长的错误消息/堆栈跟踪,其中包含:
Caused by: java.lang.ClassCastException: mount.core.NotStartedState cannot be cast to clojure.lang.IFn, compiling:(services.clj:29:23)
所以看起来 env 直到从 swagger 设置调用它之后才开始。我仍然不知道为什么当 cider-jack-in 确实起作用时,它清楚地显示了 config.env 状态在 http-server 之前开始。(看上面)