我定义了以下架构:
(s/defschema Card
{:cardNumber s/Str
:cvv s/Str
:creditCardMonthValidity s/Str
:creditCardYearValidity s/Str
:cpf s/Str
:name s/Str
:phoneNumber s/Str})
然后在路由中我在JSON响应中使用相同的键:
(GET "/card" []
:summary "fetches card info given the access token & checkout id"
:query-params [accessToken :- String checkoutId :- String]
:return Card
(let [checkout (CheckoutApi/show checkoutId accessToken)
card (.getCard checkout)
contact (.getContact checkout)
(ok {:cardNumber (.getAccountNumber card)
:cvv "000"
:creditCardMonthValidity (.getExpiryMonth card)
:creditCardYearValidity (.getExpiryYear card)
:cpf (.getNationalID contact)
:name (.getFirstName contact)
:phoneNumber (.getPhoneNumber contact)})]))
有一种优雅的方法可以避免重复键名吗?像构造函数方法,我可以传递值? (可能按某种特定顺序)
答案 0 :(得分:1)
这样的东西可以工作:你可以定义一个宏,它一次定义模式和构造函数。
user> (defmacro defresponse [schema constructor-name constructor-params data]
`(do
(s/defschema ~schema ~(into {} (map (fn [[k [t _]]] [k t])
data)))
(defn ~constructor-name ~constructor-params
~(into {} (map (fn [[k [_ init]]] [k init])
data)))))
#'user/defresponse
user> (defresponse Card card-response [card contact]
{:cardNumber [s/Str (.getAccountNumber card)]
:cvv [s/Str "000"]
:creditCardMonthValidity [s/Str (.getExpiryMonth card)]
:creditCardYearValidity [s/Str (.getExpiryYear card)]
:cpf [s/Str (.getNationalID contact)]
:name [s/Str (.getFirstName contact)]
:phoneNumber [s/Str (.getPhoneNumber contact)]})
此defresponse将扩展为以下内容:
(do
(s/defschema
Card
{:cardNumber s/Str,
:cvv s/Str,
:creditCardMonthValidity s/Str,
:creditCardYearValidity s/Str,
:cpf s/Str,
:name s/Str,
:phoneNumber s/Str})
(defn card-response [card contact]
{:cardNumber (.getAccountNumber card),
:cvv "000",
:creditCardMonthValidity (.getExpiryMonth card),
:creditCardYearValidity (.getExpiryYear card),
:cpf (.getNationalID contact),
:name (.getFirstName contact),
:phoneNumber (.getPhoneNumber contact)}))
然后您可以像往常一样使用您的架构,card-response
就像这样:
(let [checkout (CheckoutApi/show checkoutId accessToken)
card (.getCard checkout)
contact (.getContact checkout)]
(ok (card-response card contact)))
(没有测试过这个,但它应该有用。否则会在早上更新它)