You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用compojure.api生成Swagger文档时的cond-pre兼容问题

解决schema.core/cond-pre与Compojure API Swagger兼容的问题

核心原因是Compojure API的Swagger生成器默认无法自动解析cond-pre这类条件型Schema,需要手动补充Swagger元数据或改用更兼容的Schema定义方式,以下是几个简便方案:

方法1:给cond-pre添加Swagger元数据

直接在cond-pre定义中通过元数据指定Swagger可识别的oneOf类型,明确告知其支持单个对象或数组:

(schema.core/defschema Payroll
  {:id schema/Int
   :amount schema/Num})

(def PayrollOrArray
  ^{:swagger {:oneOf [(schema.core/resolve-schema Payroll)
                      (schema.core/resolve-schema [Payroll])]}}
  (schema.core/cond-pre
    Payroll
    [Payroll]))

之后在接口中使用PayrollOrArray作为请求体Schema,Swagger即可正常渲染对应的结构。

方法2:用schema.core/either替代cond-pre

either本身表示"多个类型任选其一",Compojure API的Swagger生成器对其原生支持更好,无需额外配置就能自动生成正确的文档:

(schema.core/defschema Payroll
  {:id schema/Int
   :amount schema/Num})

(def PayrollOrArray
  (schema.core/either Payroll [Payroll]))

这种方式下Swagger会自动识别为oneOf类型,展示单个Payroll对象和Payroll数组两种可选结构。

方法3:在接口中手动指定Swagger请求体结构

如果前两种方案不适用,可直接在接口的:swagger配置里强制定义请求体的Schema结构:

(POST "/payroll" []
  :body [payload PayrollOrArray]
  :swagger {:requestBody {:content {"application/json"
                                    {:schema {:oneOf [(schema.core/resolve-schema Payroll)
                                                      (schema.core/resolve-schema [Payroll])]}}}}}
  :return schema/Boolean
  (ok true))

通过这种方式直接告诉Swagger请求体的结构,也能让文档正常显示。

注意:cond-pre在运行时是按顺序匹配第一个符合的Schema,而Swagger的oneOf不区分顺序,但在单个对象和数组的场景下,这种差异几乎不会影响实际使用。

内容的提问来源于stack exchange,提问作者Lars Melander

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.02 11:34:54