Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Clojure 响应体上的compojure api规范强制_Clojure_Compojure Api - Fatal编程技术网

Clojure 响应体上的compojure api规范强制

Clojure 响应体上的compojure api规范强制,clojure,compojure-api,Clojure,Compojure Api,我试图找出如何使用compojure api和规范进行自定义强制。通过阅读文档和代码,我已经能够对输入(主体)进行强制,但无法对响应主体进行强制 具体来说,我有一个自定义类型,时间戳,在我的应用程序中表示为long,但对于web API,我希望使用并返回ISO时间戳(不,我不想在内部使用Joda) 以下是我所拥有的用于输入强制的功能,但我无法正确强制响应 (ns foo (:require [clj-time.core :as t] [clj-time.coerce

我试图找出如何使用compojure api和规范进行自定义强制。通过阅读文档和代码,我已经能够对输入(主体)进行强制,但无法对响应主体进行强制

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

以下是我所拥有的用于输入强制的功能,但我无法正确强制响应

(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))

问题在于符合规范是一条单向转换管道:

s/conform
(正因为如此,
st/conform
)对结果进行转换和验证。您的响应强制首先将整数转换为日期字符串,然后根据原始spec谓词(即
pos int?
)对其进行验证,但失败

要支持双向转换,您需要将最终结果定义为两种可能的格式之一:例如,将谓词更改为类似于
#(或(pos int?%)(string?%)
的格式,并且应该可以工作

或者您可以有两个不同的规范记录,一个用于输入(
timestamp long
pos int?
谓词),另一个用于输出(
timestamp string
string?
谓词)。但我们需要记住,在请求和响应中使用正确的方法

如果存在和额外的
:transform
模式(尚未在本期中写入),可能会有所帮助,这将在不验证最终结果的情况下实现一致性

通常,返回转换由格式编码器完成,但它们通常根据值类型进行调度。例如,Cheshire只看到一个Long,不知道它是否应该写为日期字符串


也许clojure spec slack上的人能帮上忙。我还想知道如何使用spec构建这种双向转换。

问题是spec compliance是一个单向转换管道:

s/conform
(正因为如此,
st/conform
)对结果进行转换和验证。您的响应强制首先将整数转换为日期字符串,然后根据原始spec谓词(即
pos int?
)对其进行验证,但失败

要支持双向转换,您需要将最终结果定义为两种可能的格式之一:例如,将谓词更改为类似于
#(或(pos int?%)(string?%)
的格式,并且应该可以工作

或者您可以有两个不同的规范记录,一个用于输入(
timestamp long
pos int?
谓词),另一个用于输出(
timestamp string
string?
谓词)。但我们需要记住,在请求和响应中使用正确的方法

如果存在和额外的
:transform
模式(尚未在本期中写入),可能会有所帮助,这将在不验证最终结果的情况下实现一致性

通常,返回转换由格式编码器完成,但它们通常根据值类型进行调度。例如,Cheshire只看到一个Long,不知道它是否应该写为日期字符串

也许clojure spec slack上的人能帮上忙。还想知道如何使用spec构建这种双向转换。

具有
#(或(pos int?%)(string?%)
将允许字符串通过spec,但是如何调用
t.c/to string
函数?也就是说,我如何将
时间戳->json字符串
连接到强制程序?拥有
#(或(pos int?%)(string?%)
将允许字符串通过规范,但如何调用
t.c/to string
函数?也就是说,如何将
时间戳->json字符串
连接到强制程序?