我正在学习在 clojure 中编写一个简单的 REST API,它只是通过 REST API 提供一些数据,以充当 mysql 数据库的中间件。
我遵循了一些教程并设置了我的环服务器以将 clojure 数据转换为 json。我的项目有这些依赖项:
; middleware
[compojure "1.6.2"]
[ring/ring-defaults "0.3.2"]
[ring/ring-json "0.5.1"]
[ring-cors "0.1.13"]
; API
[clj-http "3.12.3"]
[cheshire "5.11.0"]
; MYSQL
[org.clojure/clojure-contrib "1.2.0"]
[org.clojure/java.jdbc "0.7.12"]
[mysql/mysql-connector-java "8.0.33"]]
我的主处理程序文件有这样的内容:
(defroutes app-routes
(GET "/get-data" [type] (api/get-users type)))
(def app
(-> app-routes
(wrap-cors :access-control-allow-origin [#".*"]
:access-control-allow-methods [:get :put :post :delete])
(middleware/wrap-json-body {:key-fn keyword})
(middleware/wrap-json-response)))
只要返回数据是惰性序列,一切就可以正常工作。我可以卷曲 url,并获得有效的 json 数组。但是当响应只是一个没有数组的 json 对象时,我得到空响应。我尝试打印数据,并且从数据库中获取了正确的数据。然后我尝试打印每种类型响应的数据类型,并且我有不同的类型。
clojure.lang.LazySeq
-> 有效,我得到了有效的 json 响应。但是 clojure.lang.PersistentArrayMap
-> 不起作用,我得到的回复是空的。
当我在将数据返回到浏览器之前打印数据时,我得到这些:
对于惰性序列:
({:id spanish-chorizo-paella, :name Spanish chicken & chorizo paella})
// ^ this works fine and I get a JSON array in response
对于持久数组映射:
{:latest 202410-hu, :past [{:id 202212-nl-ch-fr}]}
// ^ This doesn't work and I get an empty response in browser
我需要做些什么才能让环服务器检测并转换第二种类型以正确作为 json 发送吗?
:status
、:headers
。以及可选的 :body
键。您尝试返回一些其他地图,无论 API 为您提供什么,并希望它能转换为 JSON。由于您的处理程序不遵循 Ring 规范,因此围绕它的中间件的行为是未定义的:显然,当您返回惰性序列时,它们恰好返回一些合理的内容,但这并不能保证,并且当您返回地图。
不要依赖于此,而是更新处理程序以返回响应映射,其中包含要在
:body
中编码的 JSON 正文。您可以通过返回 {:status 200 :body (api/get-users type)}
手动完成此操作,但通常会委托给 ring.util.response/response
,它会为您完成此操作。