Как получить почтовые данные JSON в Noir

Некоторое время назад Крис Грейнджер опубликовал эту промежуточную программу, чтобы получить Хеши JSON должны отображаться в параметрах defpage под зонтичным элементом «магистраль».

(defn backbone [handler]
  (fn [req]
    (let [neue (if (= "application/json" (get-in req [:headers "content-type"]))
       (update-in req [:params] assoc :backbone (json/parse-string (slurp (:body req)) true))
       req)]
    (handler neue))))

Как я могу изменить этот код, чтобы элементы JSON отображались как параметры верхнего уровня в defpage; то есть избавиться от зонтика :backbone?


person Dax Fohl    schedule 17.05.2012    source источник
comment
Почему вы хотите этого? Кажется, это может иметь катастрофические последствия, если какие-либо данные в объекте JSON переопределяют существующие атрибуты запроса. Разве это то, к чему вы стремитесь?   -  person Jeremy    schedule 17.05.2012
comment
Других атрибутов запроса нет. Все публикуется в формате JSON. Вот почему элемент зонтичной основы кажется мне избыточным.   -  person Dax Fohl    schedule 17.05.2012
comment
А, я вижу, он обновляет ключ :params, а не карту запросов... см. мой ответ.   -  person Jeremy    schedule 17.05.2012


Ответы (3)


Есть две вещи, которые вы можете сделать. Один из вариантов — заменить значение :params картой, возвращенной после синтаксического анализа JSON. Для этого просто свяжите новую карту с ключом :params.

(assoc req [:params] (json/parse-string (slurp (:body req)) true))

Другой вариант (предложенный @dAni) состоит в том, чтобы объединить значения проанализированного JSON, чтобы существующие значения на карте :params не переопределялись. Причина, по которой вам нужно использовать partial вместо простого использования merge, заключается в том, что окончательная карта является результатом объединения карт слева направо. Ваше решение работает, если вы хотите, чтобы значения из карты JSON имели приоритет.

(update-in req [:params]
  (partial merge (json/parse-string (slurp (:body req)) true)))
person Jeremy    schedule 17.05.2012
comment
Я знаю, что это старо, но нельзя ли просто использовать для этого body-params с lib-noir? - person Vagmi Mudumbai; 28.09.2014

Понятно. assoc работает только для одного элемента, поэтому вы должны поместить все под зонтик :backbone. Чтобы поместить все элементы JSON в параметры, вы должны использовать merge. Поэтому измените 4-ю строку на:

(update-in req [:params] merge (json/parse-string (slurp (:body req)) true))
person Dax Fohl    schedule 17.05.2012
comment
или (update-in req [:params] (partial merge (json/parse-string (slurp (:body req)) true))) если вы хотите, чтобы существующие параметры не были переопределены. - person DanLebrero; 17.05.2012