【问题标题】:avoiding repetition while using schema.core使用 schema.core 时避免重复
【发布时间】:2017-01-12 20:53:18
【问题描述】:

我已经定义了以下架构:

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

有没有一种优雅的方法来避免键名的重复?类似于构造函数的方法,我可以传入值? (可能按特定顺序)

【问题讨论】:

    标签: clojure compojure compojure-api


    【解决方案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)]})
    

    此取消响应将扩展为以下内容:

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

    (这个没测试过,应该可以的,不然早上更新)

    【讨论】:

      猜你喜欢
      • 2019-01-19
      • 1970-01-01
      • 1970-01-01
      • 2013-04-07
      • 1970-01-01
      • 1970-01-01
      • 2023-01-13
      • 1970-01-01
      • 2013-02-16
      相关资源
      最近更新 更多