如何在Clojure中调用分页REST API并转换对应Ruby实现逻辑
分页API请求功能Ruby转Clojure实现
原Ruby核心逻辑
原Ruby代码实现了循环调用分页API累加结果的功能,简化代码如下:
def request_paginated_data(url) results = [] response = # ... http get url response_data = response['data'] results << response_data while !response_data.nil? && response.has_key?('pagination') && response['pagination'] && response['pagination'].has_key?('hasNextPage') && response['pagination']['hasNextPage'] && response['pagination'].has_key?('endCursor') && response['pagination']['endCursor'] response = # ... http get url + response['pagination']['endCursor'] response_data = response['data'] results << response_data end results end
Clojure实现方案
Clojure中无需使用可变变量和while循环,通过loop/recur结构即可实现相同的分页迭代逻辑,完整代码如下:
(require '[clj-http.client :as client] '[clojure.data.json :as json] '[clojure.tools.logging :as log]) (defn get-paginated-data [base-url base-options] {:pre [(some? base-url) (some? base-options)]} ;; 抽离单次请求逻辑,避免重复代码 (let [request-once (fn [cursor] (let [;; 把cursor追加到查询参数中,参数名可根据实际API要求修改 options (if cursor (update base-options :query-params assoc :endCursor cursor) base-options) response @(client/get base-url options) body (:body response)] (log/debug (str "body size =" (count body))) (json/read-str body :key-fn keyword)))] ;; loop维护两个状态:已收集的结果集合、下一页游标 (loop [results [] next-cursor nil] (let [json (request-once next-cursor) current-data (:data json) has-next-page (get-in json [:pagination :hasNextPage]) end-cursor (get-in json [:pagination :endCursor])] ;; 把当前页数据加入结果集 (let [new-results (conj results current-data)] ;; 判断是否需要继续请求下一页 (if (and has-next-page end-cursor (some? current-data)) ;; 满足条件则传入新的结果集和游标递归执行 (recur new-results end-cursor) ;; 不满足条件则返回所有结果,可根据需求调整是否展平:如果每页data是数组,用(apply concat new-results)即可合并为一维数组 new-results))))))
关键逻辑说明
- 用
get-in简化多层嵌套键的读取,无需逐层判断键是否存在,路径不存在时会自动返回nil(Clojure中nil为假值,直接可用于逻辑判断) loop/recur是Clojure中实现循环的标准方式,没有栈溢出风险,同时避免了可变变量的使用- 单次请求逻辑抽离为内部函数,减少重复代码,后续要加错误处理、日志都只需要修改这一处
- 最终返回结果如果需要合并为一维数组,可把最终返回的
new-results替换为(apply concat new-results),和原Ruby返回的结构对齐
内容的提问来源于stack exchange,提问作者Edward J. Stembler
相关产品推荐
相关产品推荐

