更易读的Compojure路由

3

我正在开发一个小型 Ring/Compojure 网络应用程序,想知道是否有一种方法可以简化路由。我正在使用标准的 Clojure 解构方式,但需要向函数传递相当多的参数。

这是可以的,使用 Compojure 特定的解构方式:


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

现在情况开始变得更加糟糕。我需要让函数同时接收存储在会话中的闪存消息和电子邮件:

(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函数,但是我认为将参数提取与路由放在一起更好。这使得home-post更加纯净,更易于测试。而不是将每个函数都提供一个巨大的请求映射。

在路由定义中解构是否可以更清晰(更易读),例如使用某种从地图中提取的函数、宏等?

将解构与路由放置的利弊是什么?

1个回答

4

首先,我同意您的评估,即请求解构通常应与路由处理程序定义一起使用。 Compojure提供{{link1:Clojure解构语法的扩展}}的事实似乎也表明作者也有类似的感觉。

有几件事情可以做来减少解构表单中的重复内容。 首先,Clojure的标准{{link2:映射绑定解构}}将有助于您发布的最后一个路由。 您可以做的第一件事是合并从请求: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代码会让你发现更多简化代码,使其更加清晰简洁的方法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接