我正在尝试将compojure-api(版本1.1.12)集成到现有的基于compojure的应用程序中。尽管大多数事情都可以正常工作,但是我对现有REST调用的请求强制性存在问题,此时其用法将很难更改。
我这样定义路线:
(POST "/endpoint" request
:multipart-params
[required-strings :- (describe [s/Str] "Required, an array of strings"),
{optional-string :- (describe s/Str "An optional string") ""},
{others :- {s/Keyword s/Any} {}}]
...)
这有效,除非我尝试在请求中传递other-parameters
。例如,通过curl:
curl -F "required-strings=[\"Hello\"]" -F "others={\"a\":1.0}" ...
这会导致内容的无效请求(即状态400)错误:
{"errors":{"others":"(not (map? a-clojure.lang.PersistentVector))"}}
我使用的是默认铃声site-defaults
,并且没有修改compojure api的默认强制。我已将错误跟踪到compojure.api.coerce/coerce
。我可以看到强制程序正在处理的值,它看起来像:
{:required-strings "[\"Hello\"]"
:others "{\"a\":1.0}"}
在coerce.clj的第59行上,(coerce value)
返回一个错误(每个schema.utils/error?
)。
那么,是否不可能将JSON编码的多部分参数强制转换为Clojure映射?我可以将参数定义为字符串而不是映射,然后自己进行解析,但这违反了使用compojure-api和ring-swagger的目的。
答案 0 :(得分:1)
others
的强制转换符期望clojure映射而不是字符串。要使其工作,您必须选择。
第一个选择:添加wrap-json-params中间件并执行application/json
而不是multipart/form-data
的请求:
curl ... -H 'Content-Type: application/json' \
-d $'{
"required-strings": ["Hello"],
"others": {"a": 1.0}
}'
第二个选项:使用嵌套的参数名称添加wrap-nested-params中间件和multipart/form-data
请求:
curl ... -H 'Content-Type: multipart/form-data' \
-F "required-strings[]=Hello" \
-F "others[a]=1.0"