更具可读性的Compojure路线

时间:2014-08-22 12:09:24

标签: clojure routes compojure ring

我正在使用一个小型的Ring / Compojure webapp,我想知道是否有办法整理路线。我使用标准的Clojure解构,但需要通过该函数传递相当多的参数。

这没关系,使用Compojure Compojure特定的解构:

(POST "/login/" [email password] (login-post email password)) ; handle login attempt

现在它开始变得更糟。我需要为函数提供flash消息和存储在会话中的电子邮件:

(GET "/login/" {flash :flash {email :email} :session} (login-get flash email))

以下是通过表单提交数据的途径:

(POST "/" {{user-email :user-email} :session {title :title} :params {tags :tags} :params { content :content } :params { privacy :privacy } :params} (home-post user-email title tags content privacy))

我知道我可以使用:params将原始请求发送到home-post函数,但我不知何故觉得将参数提取与路由放在一起是一个更好的解决方案。它使主场更加纯净,更容易测试。只使用巨大的请求图提供每个函数的Instread。

路由定义中的解构能否更清晰(更易读),fx使用某种从地图中提取的函数,宏,什么?

是否可以通过路线进行解构?

1 个答案:

答案 0 :(得分:4)

首先,我同意您的评估,即请求解构通常属于路由处理程序定义。 Compojure提供an extension of Clojure's destructuring syntax这一事实似乎表明作者也有同样的感受。

您可以采取一些措施来减少解构表单中的重复。首先,Clojure的标准map binding destructuring将帮助您发布最后一条路线。您可以做的第一件事是合并您从请求:params中提取的密钥:

(POST "/" {{title :title, tags :tags, content :content, privacy :privacy} :params ...} ...)

这有点清楚,但由于你没有重命名你从:params中取出的任何值,你可以做得更好:

(POST "/" {{:keys [title tags content privacy]} :params ...} ...)

就Clojure解构语法而言,这是有用的,但你可以利用Compojure的额外解构语法来进一步干掉它。 Compojure假设您最常感兴趣的是从请求的:params键获取值,因此您可以使用向量解析来将它们拉出来:

(POST "/" [title tags content privacy] ...)

好多了。由于您仍需要从请求中获取其他值,因此您可以在绑定向量的末尾提供:as the-request以直接访问请求:

(POST "/" [title tags content privacy :as req] ...)

但请记住,此变量可以被解构。考虑到所有这些,这是您上一条路线的简化版本:

(POST "/" [title tags content privacy :as {{user-email :user-email} :session}]
  (home-post user-email title tags content privacy))

我希望这有用!你写的Clojure越多,你就越能找到简化代码的方法,使它更清晰,更简洁。