首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >构造-api规范对响应体的强制

构造-api规范对响应体的强制
EN

Stack Overflow用户
提问于 2017-10-12 05:48:46
回答 1查看 323关注 0票数 0

我试图弄清楚如何使用compojure和spec进行自定义强制。通过阅读文档和代码,我能够对输入(主体)进行强制,但无法对响应体进行强制。

具体来说,我有一个自定义类型,一个时间戳,它在我的应用程序中表示为一个长类型,但是对于我想使用的web API,我想要使用并返回ISO时间戳(不,我不想在内部使用Joda )。

下面是我为输入强制而工作的内容,但我无法适当地胁迫响应。

代码语言:javascript
复制
(ns foo
  (:require [clj-time.core :as t]
            [clj-time.coerce :as t.c]
            [spec-tools.conform :as conform]
            [spec-tools.core :as st]))


(def timestamp (st/create-spec
            {:spec pos-int?
             :form `pos-int?
             :json-schema/default "2017-10-12T05:04:57.585Z"
             :type :timestamp}))

(defn json-timestamp->long [_ val]
  (t.c/to-long val))

(def custom-json-conforming
  (st/type-conforming
   (merge
    conform/json-type-conforming
    {:timestamp json-timestamp->long}
    conform/strip-extra-keys-type-conforming)))

(def custom-coercion
  (->  compojure.api.coercion.spec/default-options
       (assoc-in [:body :formats "application/json"] custom-json-
conforming)
       compojure.api.coercion.spec/create-coercion))

;; how do I use this for the response coercion?
(defn timestamp->json-string [_ val]
  (t.c/to-string val))
;; I've tried the following but it doesn't work:
#_(def custom-coercion
  (->  compojure.api.coercion.spec/default-options
       (assoc-in [:body :formats "application/json"] custom-json-
conforming)
       (assoc-in [:response :formats "application/json"]
                 (st/type-conforming
                  {:timestamp timestamp->json-string}))
       compojure.api.coercion.spec/create-coercion))
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-10-12 20:10:40

问题是,Spec一致性是一个单向转换管道:

s/conform (正因为如此,st/conform)同时对结果进行转换和验证。您的响应强制首先将整数转换为日期字符串,并根据原始规范谓词(即pos-int? )验证它,并在此基础上失败。

要支持双向转换,需要将最终结果定义为任何一种可能的格式:例如,将谓词更改为类似于#(or (pos-int? %) (string? %))的内容,它应该可以工作。

或者您可以有两个不同的Spec记录,一个用于输入(timestamp-longpos-int?谓词),另一个用于输出(timestamp-stringstring?谓词)。但是,我们需要记住在请求和响应中使用正确的请求。

如果有和额外的:transform模式(还没有写在问题中),那么CLJ-2251可能会有所帮助,这将在不验证最终结果的情况下进行符合。

通常,返回转换是由格式编码器完成的,但是它们通常根据值类型进行分配。例如,柴郡只看到一个长,不知道它应该写成日期字符串。

也许#clojure-spec松懈的人能帮上忙。还想知道如何用规范构建这种双向转换.

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

https://stackoverflow.com/questions/46702269

复制
相关文章

相似问题

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