首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何从post返回json数据!clojure liberator中的处理程序?

如何从post返回json数据!clojure liberator中的处理程序?
EN

Stack Overflow用户
提问于 2015-01-23 18:08:36
回答 3查看 1.7K关注 0票数 6

如何使用Clojure Liberator返回json-data?下面的代码不起作用:

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

handle-created应该在post之后调用吗?

EN

回答 3

Stack Overflow用户

发布于 2016-07-21 07:36:52

:post!键关联的函数不是处理程序函数。Liberator文档称其为操作函数。

操作函数键:post!,:put!和:删除!提供适合产生副作用的要点。虽然它们像决策函数一样进行评估,但布尔值没有任何影响,下一个决策步骤是常量。上下文更新的工作原理与决策函数完全相同。

因此,您不能直接从与:post!关联的函数生成http响应。

:post!键关联的函数可以返回某些内容,并且这些内容将被合并到上下文中。

上下文更新的工作原理与决策函数完全相同。

则处理程序函数稍后可以从上下文中提取该内容,并使用它来形成http响应。与这些键关联的任何一个处理程序函数都可能随后执行::handle-ok:handle-created:handle-no-content:handle-see-other:handle-multiple-representations

decision graph确定将执行哪个处理程序。

最好只使用指向新创建的资源的location头进行响应,而不使用正文,但这里有一个创建具有JSON正文和201状态的响应的示例。

代码语言:javascript
复制
(POST "/foo" [] (resource :allowed-methods [:post]
                           :available-media-types ["application/json"]
                           :handle-created {:created "ok"}))

尝试一下:

代码语言:javascript
复制
curl -X POST "localhost/foo" 
{"created":"ok"}

您可以在其project.clj文件中查看Liberator使用的JSON库。如果你想自己生成JSON字符串,你可以这样做:

代码语言:javascript
复制
:handle-created (fn [ctx] (liberator.representation/ring-response 
                          {:status 201 :body "{created:\"ok\"}"}))

上面提到了here

票数 3
EN

Stack Overflow用户

发布于 2015-01-24 07:26:17

这就是我做这件事的方式--它似乎起作用了,但我才刚刚开始使用Liberator,所以可能有更好或更正确的方式来做这件事!

我认为您需要的是一个句柄创建的处理程序。例如:

代码语言:javascript
复制
(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)))))

我有一个由处理程序创建的处理程序,如下所示

代码语言:javascript
复制
(defn calculate-total [params]
  {:total (calc params)})

我还使用了ring/json中间件,并在我的开发环境中添加了liberator跟踪工具。Liberator跟踪工具非常方便,因为它将向响应添加标头,这些标头显示Liberator的决策点。因此,对于您的问题,它可能会显示Liberator正在使用默认的句柄创建的处理程序,该处理程序只返回头部。要返回您自己的json,您需要定义处理程序。

请注意,我没有使用post!方法。这是因为在本例中,我实际上并没有创建某种新的对象/项,比如在某种存储中添加一条记录。如果你这样做,你可能会使用post!添加记录并定义句柄创建,然后获取新记录(可能带有其他新字段,如记录id或时间戳等)并返回它。

我使用:畸形?和句柄畸形来执行基本的错误检查。如果:畸形?返回true,则调用错误处理头部,这将在json主体中返回错误状态和错误消息。我发现在json中返回错误很有帮助,这样您就可以在客户端一致地处理所有事情。

我的处理程序和中间件定义如下。请注意,由于我同时提供应用程序路由和api路由,因此它们有点复杂,因为我希望将一些中间件应用于某些路由,而将其他中间件应用于其他路由。在环/环缺省值中还有一个小错误,一旦修复,将会修改一些东西,因为目前我不能使用wrap-defaults site-api中间件。请注意wrap-trace中间件。

代码语言:javascript
复制
(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)))
票数 1
EN

Stack Overflow用户

发布于 2015-01-24 23:44:12

代码201 created用于在正文中返回指向新创建的资源的链接以及Location标头。如果您希望在body中返回新创建的资源,则应该使用200 ok。默认情况下,POST后在204 no-content处执行Liberator will end up。您需要设置:respond-with-entity? true

您的资源定义将如下所示:

代码语言:javascript
复制
(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))))

我推荐使用Ceshire来解析和生成JSON。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28107448

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档