Clojure中如何返回包含ID的Conflict冲突响应
Clojure中如何返回包含ID的Conflict冲突响应
看起来你已经搭好了基础逻辑,现在就差在冲突响应里带上已存在任务的ID对吧?我来帮你调整代码解决这个问题~
首先得指出原代码里的小问题:你现在只是通过db/insert-job返回的:amount判断任务是否存在,但这个操作没法拿到已存在任务的ID。我们需要先查询到已存在的任务记录,获取它的ID,再把ID放进冲突响应里。
调整后的代码示例
首先,我们要给原有函数改个名避免重名(两个insert-job会冲突),然后增加查询已存在任务ID的逻辑:
;; 前置检查的函数:判断同名同状态任务是否存在,存在则返回带ID的冲突响应 (defn check-and-insert-job [name status req] ;; 先查询是否存在匹配的任务,获取其ID (if-let [existing-job-id (->> {:job-name name :status status} db/find-job-by-name-and-status ; 新增的数据库查询函数 :id)] ;; 存在则返回Conflict响应,带上已存在任务的ID (conflict {:id existing-job-id}) ;; 不存在则执行正常插入逻辑 (do-insert-job req))) ;; 原有的实际插入函数,重命名避免冲突 (defn do-insert-job [req] (let [[errors job] (v/validate-job (:body req))] (if errors (unprocessable-entity {:errors errors}) (let [id (db/insert-job job)] (created (format "/jobs/%d" id) {:id id})))))
关键细节说明
- 新增数据库查询函数:你需要在
db模块里实现一个find-job-by-name-and-status函数,用来根据名称和状态查询已存在的任务ID,示例如下:
(defn find-job-by-name-and-status [params] ;; 假设用clojure.java.jdbc做数据库操作 (sql/query ["SELECT id FROM jobs WHERE job_name = ? AND status = ?" (:job-name params) (:status params)] {:row-fn :id :result-set-fn first}))
这个函数会返回匹配的第一个任务ID,如果没有匹配项则返回nil。
冲突响应传参:就像你在
created响应里传入{:id id}一样,直接把{:id existing-job-id}传给conflict函数即可——只要你的conflict响应处理函数支持接收响应体参数(大部分Web框架比如Ring的响应构造函数都是支持的)。函数名重命名:原代码里两个函数都叫
insert-job会导致命名冲突,所以把实际执行插入的函数改成do-insert-job,这样逻辑更清晰,也避免了编译错误。
这样调整后,当检测到同名同状态的任务存在时,就会返回包含该任务ID的Conflict响应啦~
备注:内容来源于stack exchange,提问作者sanaka
相关产品推荐
相关产品推荐

