2015-01-23 19 views
5

Làm thế nào để trả về dữ liệu json với Clojure Liberator? Mã này không hoạt động:Cách trả dữ liệu json từ bài đăng! xử lý trong clojure liberator?

(defresource poster [] 
     :allowed-methods [:post :options] 
     :available-media-types ["application/json"] 
     :post!  (fn [ctx] (println "posting...")) 
     :handle-created (fn [ctx] {:created "ok"})) 

Nên tạo xử lý sau khi đăng?

+0

Nhìn vào [quyết định graph Liberator] (http://clojure-liberator.github.io/ liberator/assets/img/decision-graph.svg), có thể thêm ': new? true' vào tài nguyên của bạn có thể hữu ích? (Nếu bạn thực sự muốn trả về '201 Tạo', nghĩa là.) – xsc

+0

Nó trả về 201 mà không có dữ liệu json. Tôi muốn trả về dữ liệu json với tiêu đề 201. Có thể không? – Curiosity

+0

Tôi cũng lưu ý rằng bạn có: các loại phương tiện có sẵn được định nghĩa là một chuỗi - nó phải là một vectơ của các chuỗi đại diện cho các loại phương tiện có sẵn, tức là trong trường hợp của bạn: các loại phương tiện có sẵn ["application/json"]. –

Trả lời

1

Đây là cách tôi làm - có vẻ như nó hoạt động, nhưng tôi chỉ mới bắt đầu sử dụng Liberator, vì vậy có thể có cách tốt hơn hoặc chính xác hơn để làm điều này!

Tôi nghĩ điều bạn cần là trình xử lý được xử lý. Ví dụ -

(defresource shopping-calc 
    :allowed-methods [:post] 
    :available-media-types ["application/json"] 
    :malformed? (fn [context] 
       (let [params (get-in context [:request :params])] 
        (or (empty? params) 
         (is-malformed? params)))) 
    :handle-malformed (fn [context] 
         (let [params (get-in context [:request :params])] 
         (generate-string (handle-malformed-calc params)))) 
    :handle-created (fn [context] 
        (let [params (get-in context [:request :params])] 
         (generate-string (calculate-total params))))) 

và tôi có một handler xử lý tạo ra như thế này

(defn calculate-total [params] 
    {:total (calc params)}) 

tôi cũng sử dụng chiếc nhẫn/json middleware và trong môi trường dev của tôi, thêm cơ sở giải phóng dấu vết. Cơ sở dò vết của Liberator rất tiện dụng vì nó sẽ thêm các tiêu đề vào phản hồi cho thấy các điểm quyết định cho Liberator. Vì vậy, đối với bạn vấn đề, nó có thể đã cho thấy rằng Liberator đã sử dụng xử lý mặc định xử lý tạo ra, mà chỉ trả về các tiêu đề. Để trả lại json của riêng bạn, bạn cần xác định trình xử lý.

Lưu ý rằng tôi không sử dụng bài đăng! phương pháp. Điều này là bởi vì trong ví dụ này, tôi không thực sự tạo một số loại đối tượng/mục mới, chẳng hạn như thêm bản ghi vào một số loại cửa hàng. Nếu bạn đã làm điều này, những gì bạn có thể làm sẽ được sử dụng bài! để thêm bản ghi và có xử lý tạo ra được xác định để sau đó nhận được bản ghi mới (có thể với các trường mới khác, chẳng hạn như một id hồ sơ hoặc dấu thời gian vv) và trả về nó.

Tôi sử dụng: không đúng định dạng? và xử lý-không đúng định dạng để kiểm tra lỗi cơ bản. Nếu: không đúng định dạng? trả về true, tiêu đề xử lý không đúng định dạng được gọi, trả về một trạng thái lỗi và một thông báo lỗi trong phần thân json. Tôi tìm thấy nó giúp rất nhiều để có lỗi của bạn cũng trở lại trong json để bạn có thể xử lý tất cả mọi thứ liên tục trên đầu khách hàng.

Trình xử lý và định nghĩa phần mềm trung gian của tôi dưới đây. Lưu ý rằng khi tôi đang phục vụ cả hai ứng dụng và các tuyến api, chúng phức tạp hơn một chút vì tôi muốn một số phần mềm trung gian được áp dụng cho một số tuyến đường và phần mềm trung gian khác được áp dụng cho những người khác. Ngoài ra còn có một lỗi nhỏ trong vòng/mặc định vòng mà, một khi cố định, sẽ sửa đổi những thứ như hiện tại tôi không thể sử dụng các phần mềm trung gian mặc định trang web bọc-api. Lưu ý phần mềm trung gian bọc dấu vết.

(def app 
    (if (env :dev) 
    (routes (-> api-routes 
       (wrap-reload) 
       (wrap-routes wrap-json-params) 
       (wrap-routes wrap-defaults api-defaults) 
       (wrap-routes wrap-trace :header :ui)) 
      (-> app-routes 
       (wrap-routes wrap-error-page) 
       (wrap-routes wrap-exceptions))) 
    (routes (-> api-routes 
       (wrap-routes wrap-json-params) 
       (wrap-routes wrap-defaults api-defaults)) 
      app-routes))) 
+0

Cảm ơn bạn. Tôi đã dành chút thời gian để nghiên cứu đồ thị của nhà giải phóng hôm qua và giờ nó đang hoạt động với bài đăng! và xử lý được tạo ra. Có lẽ hôm qua tôi đã quá mệt mỏi. Tôi cũng đã thực hiện trở lại từ xóa! phương pháp thêm trả lời-với-thực thể? với đúng và xử lý xử lý-ok là kết quả của hoạt động xóa. – Curiosity

1

201 created được sử dụng để quay trở lại liên kết đến các tài nguyên mới được tạo ra trong cơ thể cùng với một tiêu đề Location. Nếu bạn muốn trả lại tài nguyên mới được tạo trong cơ thể, bạn nên sử dụng 200 ok. Theo mặc định, Liberator will end up tại 204 no-content sau POST. Bạn sẽ cần phải đặt :respond-with-entity? true.

định nghĩa tài nguyên Bạn sẽ trông như thế:

(defresource poster [] 
    :allowed-methods [:post :options] 
    :available-media-types ["application/json"] 
    :malformed? (fn [ctx] 
       [false {::resource (parse-json (get-in ctx [:request :body]))}]) 
    :post! (fn [ctx] 
      (persist (::resource ctx))) 
    :handle-ok (fn [ctx] 
       (generate-json (::resource ctx)))) 

Tôi khuyên bạn nên Ceshire để phân tích và tạo ra JSON.

3

Chức năng được liên kết với khóa :post! không phải là chức năng xử lý. Các tài liệu Liberator gọi nó là một chức năng hành động.

Chức năng hành động Các phím: đăng !,: put! và: xóa! cung cấp các điểm phù hợp để ban hành các tác dụng phụ.Trong khi chúng được đánh giá như các hàm quyết định, giá trị boolean không có hiệu lực và bước quyết định tiếp theo là không đổi. Bản cập nhật ngữ cảnh hoạt động chính xác như đối với các chức năng quyết định .

Vì vậy, bạn không thể tạo phản hồi http trực tiếp từ hàm được liên kết với :post!.

Chức năng được liên kết với khóa :post! có thể trả lại nội dung nào đó và thứ gì đó sẽ được hợp nhất vào ngữ cảnh.

Cập nhật ngữ cảnh hoạt động chính xác như đối với các chức năng quyết định.

Sau đó, một hàm xử lý sau đó có thể kéo thứ gì đó ra khỏi ngữ cảnh và sử dụng nó để tạo câu trả lời http. Có thể là bất kỳ một trong các chức năng xử lý kết hợp với các phím này có thể thực hiện sau đó: :handle-ok, :handle-created, :handle-no-content, :handle-see-other, :handle-multiple-representations

decision graph này xác định xử lý sẽ thực hiện.

Tốt nhất là chỉ phản hồi với tiêu đề vị trí trỏ đến tài nguyên mới được tạo và không có nội dung, nhưng đây là một ví dụ về cách tạo phản hồi với nội dung JSON và trạng thái 201.

(POST "/foo" [] (resource :allowed-methods [:post] 
          :available-media-types ["application/json"] 
          :handle-created {:created "ok"})) 

Đang cố gắng nó ra:

curl -X POST "localhost/foo" 
{"created":"ok"} 

Bạn có thể thấy JSON thư viện Liberator sử dụng trong tập tin project.clj của nó. Nếu bạn muốn tạo ra chuỗi JSON mình bạn có thể làm điều đó như thế này:

:handle-created (fn [ctx] (liberator.representation/ring-response 
          {:status 201 :body "{created:\"ok\"}"})) 

Nó được đề cập here

Các vấn đề liên quan