HTTP 概览

HTTP 概览

AdonisJS 主要是一个用来创建响应 HTTP 请求的应用的 Web 框架。在本指南中,我们将了解 AdonisJS 如何启动 HTTP 服务器、处理传入的请求,以及 HTTP 层可用的模块。

HTTP 层

AdonisJS 应用内部的 HTTP 层由以下模块组成。值得说明的是,AdonisJS 的 HTTP 层是从零开始构建的,底层并没有使用任何微框架。

Router

router 模块 负责定义应用的端点,也就是所谓的路由。一个路由应当定义一个负责处理请求的 handler。该 handler 可以是一个闭包,也可以是对某个控制器的引用。

Controllers

控制器是你绑定到路由上以处理 HTTP 请求的 JavaScript 类。控制器充当组织层,帮助你将应用的业务逻辑划分到不同的文件/类中。

HttpContext

AdonisJS 会为每个传入的 HTTP 请求创建 HttpContext 类的一个实例。HttpContext(即 ctx)携带了给定请求的信息,例如请求体、请求头、已认证的用户等。

Middleware

AdonisJS 中的中间件管道是对责任链(Chain of Responsibility)设计模式的实现。你可以使用中间件在 HTTP 请求到达路由 handler 之前拦截并响应它们。

Global Exception handler

全局异常处理器在一个集中的位置处理 HTTP 请求期间抛出的异常。你可以使用全局异常处理器将异常转换为 HTTP 响应,或者将它们上报给外部的日志服务。

Server

server 模块 将路由器、中间件和全局异常处理器连接在一起,并导出一个handle 函数,你可以将它绑定到 Node.js HTTP 服务器上以处理请求。

AdonisJS 如何启动 HTTP 服务器

HTTP 服务器是在你调用 Server 类上的 the boot method 时启动的。在底层,该方法执行以下操作。

  • 创建中间件管道
  • 编译路由
  • 导入并实例化全局异常处理器

在典型的 AdonisJS 应用中,boot 方法由 bin/server.ts 文件中的 Ignitor 模块调用。

此外,在调用 boot 方法之前定义路由、中间件和全局异常处理器是至关重要的,而 AdonisJS 通过使用 start/routes.tsstart/kernel.ts 预加载文件 来实现这一点。

HTTP 请求生命周期

既然我们已经有了一个正在监听传入请求的 HTTP 服务器,让我们来看看 AdonisJS 如何处理一个给定的 HTTP 请求。

创建 HttpContext

作为第一步,server 模块会创建 HttpContext 类的一个实例,并将其作为引用传递给中间件、路由 handler 和全局异常处理器。

如果你启用了 AsyncLocalStorage,那么同一个实例会被共享为本地存储状态。

执行 server 中间件栈

接下来,server 中间件栈 中的中间件会被执行。这些中间件可以在请求到达路由 handler 之前拦截并响应请求。

此外,即使你没有为给定端点定义任何路由,每个 HTTP 请求都会经过 server 中间件栈。这使得 server 中间件能够在不依赖路由系统的情况下为应用添加功能。

查找匹配的路由

如果 server 中间件没有结束请求,我们会为 req.url 属性查找匹配的路由。当不存在匹配的路由时,请求会以 404 - Not found 异常中止。否则,我们会继续处理该请求。

执行路由中间件

一旦存在匹配的路由,我们就会执行路由全局中间件命名中间件栈。同样,中间件可以在请求到达路由 handler 之前拦截请求。

执行路由 handler

作为最后一步,请求到达路由 handler,并带着一个响应返回给客户端。

假设在流程的任意步骤中抛出了异常,那么请求将被移交给全局异常处理器,由它负责将异常转换为响应。

序列化响应

一旦你使用 response.send 方法定义了响应体,或者从路由 handler 返回了一个值,我们就会开始响应序列化过程,并设置相应的请求头。

了解更多关于响应体序列化的内容