如何删除请求验证中的重复?

时间:2013-08-09 20:19:49

标签: clojure

我有一个包含一组路由和处理程序的compojure应用程序。

(defroutes app-routes
  (GET "/stuff/:id" [:as request] (stuff/get-stuff request))
  (POST "/stuff/" [:as request] (stuff/create-stuff request))

每个处理程序验证其输入,如此

(defn create-stuff
  [request]
  (my-validation/validate-request
    request
    my-validation/create-stuff-validator
    stuff-ok-fn))

验证码基于Metis,如下所示:

(metis/defvalidator :create-stuff-validator
  [:db :presence])

(defn validate-request
  [request request-validator ok-function]
  (let [validation-result (request-validator request)]
    (if (empty? validation-result)
      (ok-function request)
      (bad-request validation-result))))

我的问题是create-stuff中的代码在每个路由处理程序中都是重复的; get-stuff函数看起来像create-stuff处理程序。唯一不同的是它们的验证器功能和它们的验证功能。

如何以惯用的Clojure方式抽象出这种重复?

1 个答案:

答案 0 :(得分:1)

由于这是一种函数式语言,我建议将处理程序区分的函数传递给通用处理函数。

;;; in core.clj
(defroutes app-routes
  (GET "/stuff/:id" [:as request]
       (handlers/handle
        my-validation/get-stuff-validator
        stuff/get-stuff-ok-fn
        request))
  (POST "/stuff/" [:as request]
        (handlers/handle
         my-validation/create-stuff-validator
         stuff/create-stuff-ok-fn
         request)))

;;; in handlers.clj

(defn handle
  [validator action request]
  (let [validation-result (validator request)]
    (if (empty? validation-result)
      (action request)
      (bad-request validation-result))))

从风格上讲,如果你避免使用the smurf naming convention,我建议代码更易于阅读。命名空间告诉我们您是否正在验证,或者“东西”是您正在操作的东西,您不需要将它包含在函数的名称中。另外,你传递一个应该是可调用的参数的事实就足够了,你不需要在函数的名称中加入fn,因为ok分支告诉我们这是事情要做的事实当事情顺利的时候。

;;; in core.clj
(defroutes app-routes
  (GET "/stuff/:id" [:as request]
       (handlers/handle
        my-validation/get-stuff
        stuff/get
        request))
  (POST "/stuff/" [:as request]
        (handlers/handle
         my-validation/create-stuff
         stuff/create
         request)))

;;; in handlers.clj

(defn handle
  [validator ok request]
  (let [errors (validator request)]
    (if (empty? errors)
      (ok request)
      (bad-request errors))))

如果你可以在不失去清晰度的情况下减少冗长,就可以提高正确性,因为错误会隐藏在冗长中。