《Clojure Web开发实战》——第2章,第2.2节定义Compojure路由

简介:

本节书摘来自异步社区《Clojure Web开发实战》一书中的第2章,第2.2节定义Compojure路由,作者[美]Dmitri Sotnikov,更多章节内容可以访问云栖社区“异步社区”公众号查看

2.2 定义Compojure路由
Compojure是构建在Ring之上的路由库,它提供的方式非常简洁,用来关联处理URL和HTTP方法。Compojure路由基本上是这样子的:
(GET "/:id" [id] (str "<p>the id is: " id "</p>" ))
其路由函数名与HTTP方法名直接对应,比如GET、POST、PUT、DELETE和HEAD。还有一个称为ANY的路由会响应客户端任何方法。URI是包含冒号的键名,对应的那些值可以用作路由参数,Rails12和Sinatra13就是使用类似的处理机制,而Compojure正是受到这种特性的启发。上面的Ring回应描述中会自动包含路由回应。
其实在我们的实际应用中,可能会存在多条路由,Compojure提供了路由功能,能从多条路由中创建一个Ring处理。假设我们有/foo路由和/:id项,那么我们可以使用单条处理进行如下合并:
(defn foo-handler []
 "foo called")

(defn bar-handler [id]
 (str "bar called, id is: " id))

(def handler
 (routes
  (GET "/foo")
   (GET "/bar/:id foo" [id] (bar-handler id))))
定义路由是一种很常见的操作,Compojure还提供了defroutes宏,通过给定的路由生成一个Ring处理程序:
(defroutes handler  (GET "/foo" []    (foo-handler))  (GET "/bar/:id" [id] (bar-handler id)))
使用Compojure路由,可以非常方便地将网站的每个URL映射到功能代码,并且提供Web应用的大部分核心功能。我们可以像前面那样,使用defroutes宏把这些路由组织起来。大致上,Compojure就是这样维护Ring处理的。
对基于路径共享的程序,Compojure也提供强大的过滤机制处理常见路由。假设我们现有多条路由来响应特定用户:
(defn display-profile [id]  ;;TODO: display user profile  ) (defn display-settings [id]  ;;TODO: display user account settings  ) (defn change-password [id]  ;;TODO: display the page for setting a new password  ) (defroutes user-routes  (GET "/user/:id/profile" [id] (display-profile id))  (GET "/user/:id/settings" [id] (display-settings id))  (GET "/user/:id/change-password" [id] (change-password-page id))
现在每条路由前段都是/user/:id,必然会有很多重复代码。我们可以使用context宏,来解析路由的相同部分。
(def user-routes    (context "/user/:id" [id]      (GET "/profile" [] (display-profile id))      (GET "/settings" [] (display-settings id))      (GET "/change-password" [] (change-password-page id))))
这段代码中,路由定义了与/user/:id有关的内容,和前一个版本功能完全一样,都能使用id参数。context宏正是通过闭包来实现的。输出handler封装了通用参数,它们就可以在内部定义。
访问请求参数
有些路由,需要我们使用请求的map保存请求参数。我们通过以下这种方式声明map,并作为路由的第二参数:
(GET "/foo" request (interpose ", " (keys request))) 此路由提取请求map的所有键名,并罗列出来,其输出如下。 :ssl-client-cert, :remote-addr, :scheme, :query-params, :session, :form-params, :multipart-params, :request-method, :query-string, :route-params, :content-type, :cookies, :uri, :server-name, :params, :headers, :content-length, :server-port, :character-encoding, :body, :flash
Compojure同样提供一些实用功能来处理请求map,包括格式化参数之类。例如,在留言簿程序中(第1章“起步”,第1页),我们看到如下路由定义:
(POST "/" [name message] (save-message name message))
这个路由从请求参数中提取了:name 和:message两个键,然后将它们绑定给同名变量。就像其他的声明变量一样,现在,我们在路由作用范围内就可以使用了。
常规的Clojure解构也可用于路由内部,假设给定一个包含如下参数的请求map:
{:params {"name" "some value"}}
我们可以使用这种方式从参数中提取“name”关键字:
(GET "/:foo" { {value "name"} :params}  (str "The value of name is " value))
此外,Compojure 还提供解构形参子集,并用剩余部分创建一个map:
[x y & z] x -> "foo" y -> "bar" z -> {:v "baz", :w "qux"}
以上代码中,参数x和y都绑定到变量,v和w被重命名为一个名为z的map。此外,如果我们需要完整的请求参数,我们还可以进行如下处理:
(GET "/" [x y :as r]
这里,我们将形参绑定给x、y,还有完整的请求map绑定给变量r。Ring和Compojure装备上函数式这种强劲的武器,我们就能轻易创建页面,并为站点提供路由。但是,完善的应用还需要许多其他的特性,比如页面缓存、会话管理、输入验证,面对这些任务,我们使用最棒的适配器库来逐个击破。

相关文章
|
移动开发 前端开发 API
深入理解前端路由:构建现代 Web 应用的基石(上)
深入理解前端路由:构建现代 Web 应用的基石(上)
深入理解前端路由:构建现代 Web 应用的基石(上)
|
前端开发 JavaScript API
前端路由:构建现代Web应用的导航之道
在构建现代Web应用程序时,前端路由是不可或缺的一部分。它允许用户在应用内导航,同时保持URL的同步,使应用看起来像一个多页面应用程序。本博客将深入研究前端路由的核心概念、实现方式、最佳实践以及如何为您的Web应用程序创建流畅的导航体验。
184 0
|
3月前
|
开发框架 JSON 中间件
Go语言Web开发框架实践:路由、中间件、参数校验
Gin框架以其极简风格、强大路由管理、灵活中间件机制及参数绑定校验系统著称。本文详解其核心功能:1) 路由管理,支持分组与路径参数;2) 中间件机制,实现全局与局部控制;3) 参数绑定,涵盖多种来源;4) 结构体绑定与字段校验,确保数据合法性;5) 自定义校验器扩展功能;6) 统一错误处理提升用户体验。Gin以清晰模块化、流程可控及自动化校验等优势,成为开发者的优选工具。
|
API 网络架构 开发者
Flask Web开发基础【路由和Jinja2模板引擎】
# Flask Web开发基础 Flask是轻量级Web框架,专注于核心功能:请求响应、模板渲染和URL路由。本文档介绍了使用Flask的基础知识,包括命令行和Python两种运行模式,以及如何修改入口文件、端口和地址。此外,还讨论了URL路由的概念和其在Flask中的实现,展示了动态路由和多URL绑定的例子。最后,提到了Jinja2模板引擎,解释了其基本语法,并通过电影列表案例展示了如何结合Flask使用模板。
151 1
|
12月前
|
缓存 中间件 网络架构
Python Web开发实战:高效利用路由与中间件提升应用性能
在Python Web开发中,路由和中间件是构建高效、可扩展应用的核心组件。路由通过装饰器如`@app.route()`将HTTP请求映射到处理函数;中间件则在请求处理流程中插入自定义逻辑,如日志记录和验证。合理设计路由和中间件能显著提升应用性能和可维护性。本文以Flask为例,详细介绍如何优化路由、避免冲突、使用蓝图管理大型应用,并通过中间件实现缓存、请求验证及异常处理等功能,帮助你构建快速且健壮的Web应用。
92 1
|
JSON 中间件 数据处理
实践出真知:通过项目学习Python Web框架的路由与中间件设计
【7月更文挑战第19天】探索Python Web开发,掌握Flask或Django的关键在于理解路由和中间件。路由连接URL与功能,如Flask中@app.route()定义请求响应路径。中间件在请求处理前后执行,提供扩展功能,如日志、认证。通过实践项目,不仅学习理论,还能提升构建高效Web应用的能力。示例代码展示路由定义及模拟中间件行为,强调动手实践的重要性。
144 1
|
监控 测试技术 开发者
【Docker项目实战】使用Docker部署NextTrace Web路由工具
【6月更文挑战第16天】使用Docker部署NextTrace Web路由工具
230 5
|
开发框架 开发者 Python
使用 Flask 为 Web 应用添加路由
通过学习 Flask 中的视图函数和路由规则,你可以使用 Flask 构建强大的 Web 应用程序并为其添加功能。在 Flask 中,视图函数以 Python 函数的形式定义,每个视图函数都与一个 URL 相关联。在 Flask 中,URL 处理程序被称为视图函数,它们用于响应客户端请求并返回响应。在 Flask 应用程序中,这是可选的。在这里,我们将其命名为 'hello',并将其与 URL '/hello/<name>' 绑定在一起。在上面的示例中,我们使用了默认的视图函数名称 'hello'。
131 2
|
开发框架 .NET PHP
Web服务搭建&站库分离&路由访问
Web服务搭建&站库分离&路由访问
103 1
|
API 网络架构 开发者
探索Python Web框架的核心:路由机制详解
【7月更文挑战第21天】Python Web开发中,Flask和Django的路由机制解析:Flask用@app.route装饰器绑定URL到视图,如`@app.route(&#39;/user/&lt;username&gt;&#39;)`;Django通过urls.py配置URL模式,如`path(&#39;user/&lt;str:username&gt;/&#39;, views.user_profile, name=&#39;user_profile&#39;)`。两者都支持静态、动态路由和HTTP方法绑定,展现路由灵活性,助力构建高效Web应用。
134 0