clojure - Compojure-api:请求强制通过 multipart-params 提供的地图
问题描述
我正在尝试将 compojure-api(版本 1.1.12)集成到现有的基于 compojure 的应用程序中。虽然大多数事情都有效,但我在现有 REST 调用上的请求强制存在问题,此时其用法很难更改。
- 这是一个帖子
- 它期望通过 multipart/form-data 参数
- 大多数参数是可选的。
- 大多数参数都很简单:字符串或字符串数组。
- 一个可选参数应为 JSON 编码的地图。
我这样定义路线:
(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))"}}
我正在使用 ring-default's site-defaults
,并且我没有修改 compojure api 的默认强制。我已将错误追踪到compojure.api.coerce/coerce
. 我可以看到强制器正在处理的值,它看起来像:
{:required-strings "[\"Hello\"]"
:others "{\"a\":1.0}"}
在 coerce.clj 的第 59 行,(coerce value)
返回一个错误 (per schema.utils/error?
)。
那么,是否不可能将 JSON 编码的多部分参数强制转换为 Clojure 映射?我可以将参数定义为字符串而不是映射,并自己进行解析,但这违背了使用 compojure-api 和 ring-swagger 的目的。
解决方案
for 的强制器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"
推荐阅读
- java - 使用 Spring Boot 在 thymeleaf 模板中打印数据时出现问题
- gitlab - Gitlab EE 12.8.5-ee Ultimate 禁用了 Gitlab 拉镜像选项
- assembly - 用于处理两个分支结果的流水线处理器设计
- r - R:建立积分矩阵的最快方法?
- asp.net-core - 在 ASP.NET Core 3.x Endpoints 路由中,如何指定域名?
- android - 讲解android文件和存储结构
- java - Kolmogorov-Smirnov 2 Sample Test Java 给出 0 p 值
- python - 如何在 Databricks 上使用 HoloViews / hvPlot
- linux - Kubernetes 卷挂载
- python - Int 不是关键字,如果我们将它用作变量会发生什么?