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

如何在Clojure中迁移OpenAPI的requestBody/responses到components并生成$ref

OpenAPI规范Clojure数据迁移完整实现

核心需求

将:paths下各端点的:requestBody迁移至:components/:requestBodies,:responses迁移至:components/:responses,原位置替换为$ref引用,同时保留:parameters节点不变。

实现思路

  1. 初始化组件节点:保留原规范中已有的:components内容,若无则创建空的:requestBodies和:responses。
  2. 遍历所有路径与HTTP方法:逐个处理每个端点的请求体和响应定义。
  3. 生成唯一引用键:基于路径、方法和类型生成可读性强的唯一键,确保引用不冲突。
  4. 迁移并替换:将请求体/响应内容存入对应组件节点,原位置替换为$ref引用。
  5. 合并结果:将修改后的路径和更新后的组件合并回原规范数据。

完整代码实现

(ns openapi-migrator.core
  (:require [clojure.string :as str]))

;; 生成唯一引用键:路径替换斜杠为下划线,拼接方法和类型
(defn generate-ref-key [path method type]
  (str (str/replace (subs path 1) "/" "_") "_" (name method) "_" type))

;; 处理单个方法的requestBody:迁移至components并替换为$ref
(defn process-request-body [path method method-data components]
  (if-let [req-body (:requestBody method-data)]
    (let [ref-key (generate-ref-key path method "requestBody")
          updated-components (update components :requestBodies assoc ref-key req-body)
          updated-method (assoc method-data :requestBody {"$ref" (str "#/components/requestBodies/" ref-key)})]
      [updated-method updated-components])
    [method-data components]))

;; 处理单个方法的responses:逐个迁移响应至components并替换为$ref
(defn process-responses [path method method-data components]
  (if-let [responses (:responses method-data)]
    (let [[updated-responses updated-components]
          (reduce (fn [[resp-map comps] [status-code resp]]
                    (let [ref-key (generate-ref-key path method (str "response_" status-code))
                          new-comps (update comps :responses assoc ref-key resp)]
                      [(assoc resp-map status-code {"$ref" (str "#/components/responses/" ref-key)}) new-comps]))
                  [{} components]
                  responses)]
      [(assoc method-data :responses updated-responses) updated-components])
    [method-data components]))

;; 处理单个路径下的所有HTTP方法
(defn process-path [path path-data components]
  (reduce (fn [[updated-path comps] [method method-data]]
            (let [[method-with-ref1 comps1] (process-request-body path method method-data comps)
                  [method-with-ref2 comps2] (process-responses path method method-with-ref1 comps1)]
              [(assoc updated-path method method-with-ref2) comps2]))
          [{} components]
          path-data))

;; 主函数:执行完整迁移逻辑
(defn migrate-to-components [openapi-spec]
  ;; 初始化组件:保留原有内容,若无则创建空节点
  (let [initial-components (merge {:requestBodies {} :responses {}} (:components openapi-spec))
        ;; 遍历所有路径,处理后得到更新的路径和组件
        [updated-paths final-components]
        (reduce (fn [[paths comps] [path path-data]]
                  (let [[new-path-data new-comps] (process-path path path-data comps)]
                    [(assoc paths path new-path-data) new-comps]))
                [{} initial-components]
                (:paths openapi-spec))]
    ;; 合并回原规范数据
    (assoc openapi-spec
           :paths updated-paths
           :components final-components)))

使用示例

;; 测试用OpenAPI规范
(def sample-spec
  {:openapi "3.0.0"
   :paths {"/users" {:post {:requestBody {:content {"application/json" {:schema {:type "object" :properties {:name {:type "string"}}}}}}
                           :responses {"200" {:description "OK" :content {"application/json" {:schema {:type "object" :properties {:id {:type "integer"}}}}}}}}
           "/users/{id}" {:get {:parameters [{:name "id" :in "path" :required true :schema {:type "integer"}}]}
                               :responses {"200" {:description "User found" :content {"application/json" {:schema {:type "object" :properties {:name {:type "string"}}}}}}}}}})

;; 执行迁移
(migrate-to-components sample-spec)

关键细节说明

  • 引用键生成:默认用路径+方法+类型生成可读键,若需去重(相同内容复用引用),可替换为基于内容哈希的键,例如:
    (defn generate-ref-key [content type]
      (str type "_" (hash content)))
    
  • 组件合并:使用merge保留原规范中已有的:components内容,避免覆盖自定义组件。
  • 参数保留:代码中未修改:parameters节点,确保原参数定义完全保留。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 04:17:11