Compojure-api: запрос приведения для карты, предоставленной через multipart-params - PullRequest
0 голосов
/ 29 июня 2018

Я пытаюсь интегрировать 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))"}}

Я использую кольцо по умолчанию site-defaults, и я не изменил приведенные по умолчанию приведения для API compojure. Я отследил ошибку до compojure.api.coerce/coerce. Я вижу значение, над которым работает coercer, и оно выглядит так:

{:required-strings "[\"Hello\"]"
 :others "{\"a\":1.0}"}

В строке 59 файла coerce.clj (coerce value) возвращает ошибку (для schema.utils/error?).

Итак, нельзя ли принудительно привести JSON-закодированный многокомпонентный параметр к карте Clojure? Я могу определить параметр как строку вместо карты и выполнить синтаксический анализ самостоятельно, но это лишает смысла использование compojure-api и ring-swagger.

1 Ответ

0 голосов
/ 24 июля 2018

Для coercer для others ожидается карта замыкания, а не строка. Чтобы это работало, у вас есть варианты.

Первый вариант: добавить wrap-json-params middleware и выполнить application/json запрос вместо multipart/form-data:

curl ... -H 'Content-Type: application/json' \
     -d $'{
  "required-strings": ["Hello"],
  "others": {"a": 1.0}
}'

Второй вариант: добавить wrap-nested-params middleware и multipart/form-data запрос с использованием имен вложенных параметров:

curl ... -H 'Content-Type: multipart/form-data' \
     -F "required-strings[]=Hello" \
     -F "others[a]=1.0" 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...