Почему я должен сглаживать вложенный JSON при использовании промежуточного программного обеспечения кольцевого json

Я пишу приложение clojure с кольцом и compojure. Я использую промежуточное ПО ring.middleware.json для обработки JSON, поэтому мне не нужно сериализовать и десериализовать его самостоятельно в моем коде.

Это промежуточное ПО, кажется, правильно анализирует вложенный JSON только в том случае, если он задан в плоском формате, например, если я хочу отправить вложенные данные POST на маршрут API, я должен закодировать его как:

{"task"            : 1,
 "success"         : false,
 "files[0][type]"   : "log",
 "files[0][sha256]" : "adef5c",
 "files[0][url]"    : "s3://url"}

Вместо, как мне кажется, более стандартного JSON:

{"task"    : 1,
 "success" : false,
 "files"   : [{"type" : "log", "sha256" : "adef5c", "url": "s3://url"}]}

Это отступ или стандартный способ публикации вложенного JSON? Вот мой стек промежуточного ПО:

(defn middleware [handler]
  (-> handler
    (wrap-json-response)
    (wrap-with-logger)
    (api)))

person Michael Barton    schedule 09.02.2016    source источник


Ответы (1)


Вот полный пример маршрутов post и get на Clojure, которые обрабатывают JSON или возвращают JSON:

(ns ring-app.core
  (:require [ring.adapter.jetty :as jetty]
            [compojure.core :as compojure]
            [ring.middleware.keyword-params :refer [wrap-keyword-params]]
            [ring.middleware.json :refer [wrap-json-response wrap-json-body]]
            [ring.util.http-response :as response]
            [clojure.pprint :refer [pprint]]
            [ring.middleware.reload :refer [wrap-reload]]))

(defn json-get [request]
  (response/ok 
    {"task"  1 
     "success"  false  
     "files" [{"type"  "log" "sha256"  "adef5c" "url"  "s3://url"}]}))

(defn json-post [request]
  (let [bpdy (:body request)]
    (prn bpdy)
    (response/ok bpdy)))

(compojure/defroutes handler_
 (compojure/GET "/get" request json-get)
 (compojure/POST "/post" request json-post))

(defn wrap-nocache [handler]
  (fn [request]
    (-> request
        handler
        (assoc-in [:headers "Pragma"] "no-cache"))))

(def handler 
  (-> #'handler_ wrap-nocache wrap-reload wrap-json-response wrap-json-body ) )

Конечная точка get возвращает вложенную структуру:

curl http://localhost:3000/get
; {"task":1,"success":false,"files":[{"type":"log","sha256":"adef5c","url":"s3://url"}]}                                    

И конечная точка POST анализирует json и создает структуру данных Clojure:

  curl -X post  -d '{"task":1,"success":false,"files":[{"type":"log","sha256":"adef5c","url":"s3://url"}]}'  -H "Accept: application/json" -H "Content-type: application/json"  http://localhost:3000/post
  ; {"task":1,"success":false,"files":[{"type":"log","sha256":"adef5c","url":"s3://url"}]}

Это круговой обмен на JSON-> CLJ-> JSON

Промежуточное программное обеспечение json ring ожидает, что Content-type будет правильно установлен, поэтому, возможно, именно поэтому структура не была правильно проанализирована в вашем случае?

person Nicolas Modrzyk    schedule 09.02.2016
comment
Спасибо, я не устанавливал Content-type в своем запросе. Добавление этого решило мою проблему. - person Michael Barton; 09.02.2016