Guide

应用实例

应用实例是 h3 服务器的核心。

h3 服务器的核心是一个 app 实例。它是处理传入请求的服务器核心。您可以使用应用实例注册事件处理程序。

初始化一个应用

您可以使用 createApp 工具创建一个新的 h3 应用实例:

app.mjs
import { createApp } from "h3";

const app = createApp();

设置全局选项

在初始化应用时,您可以传递全局应用配置。

示例: 创建一个启用详细日志记录的应用。

const app = createApp({
  debug: true,
});

设置全局钩子

在初始化 h3 应用时,您可以注册全局钩子:

  • onError
  • onRequest
  • onBeforeResponse
  • onAfterResponse

这些钩子会在每个请求中被调用,可以用来为您的应用添加全局逻辑,例如日志记录、错误处理等。

const app = createApp({
  onError: (error) => {
    console.error(error);
  },
  onRequest: (event) => {
    console.log("请求:", event.path);
  },
});

注册事件处理程序

您可以使用 app.use事件处理程序 注册到应用实例:

app.use("/hello", () => "你好,世界!");

这将把事件处理程序注册到应用实例,并将在每个以 /hello 开头的请求中被调用。这意味着事件处理程序将被调用 /hello/hello/world/hello/123 等。

您可以为同一路由定义多个事件处理程序。h3 将尝试按注册顺序逐个调用它们,直到其中一个返回响应。这称为 堆栈运行器

app.use("/", () => "第一个");
app.use("/", () => "第二个");

在这个例子中,第一个事件处理程序将会被所有以 /hello 开头的请求调用,而第二个则不会被调用。

然而,如果您不从第一个事件处理程序返回响应,第二个将会被调用。这对于实现 中间件 模式非常有用。

app.use("/", () => {
  console.log("第一个");
  // 未返回响应
});
app.use("/", () => "第二个");

如果所有处理程序都被调用且没有返回响应,h3 将以 404 状态响应结束请求。

使用空的 returnreturn undefined 会返回 404 Not Found 状态响应。 同样使用 return null 会返回 204 No Content 状态响应。
使用 return {}return ""return true 来明确返回响应。

事件处理程序选项

use 方法接受一个可选的 options 对象作为第三个参数:

app.use("/hello", () => "你好,世界!", {
  // 选项
});
matcher

您可以定义一个自定义匹配器函数,以便为请求匹配提供更高级的逻辑,但比路由更简单。

例如,您可以只匹配奇数 URL,/1/3/5 等:

lazy

您可以提供一个异步函数,h3 会在首次接收到匹配该路由的请求时加载它。它对于动态导入非常有用,以减少启动时间。

app.use("/", () => "仅奇数 URL", {
  match: (url) => {
    return url.substr(1) % 2;
  },
});
不要将自定义匹配器用作路由器。它不为该目的而设计。请使用 路由器
app.use("/big", () => import("./big-handler"), { lazy: true });

这减少了启动时间,因为在启动服务器时运行时需要加载和解析的代码更少。

内部实现

这些详情主要是供参考。绝不要 在生产应用中直接使用内部实现!

h3 应用实例有一些额外的属性。然而,通常不建议直接访问它们,除非您知道自己在做什么!

  • app.stack: 当前注册的事件处理程序的有序数组。
    • 每个项目都有 routehandler 属性。
  • app.options: 在初始化应用时提供的全局选项对象。
  • app.handler: 直接的堆栈处理函数(不安全,不能直接调用)。