routes 属性(静态路径、参数和通配符)向 Bun.serve() 添加路由,或使用 fetch 方法处理未匹配的请求。
Bun.serve() 的路由器基于 uWebSocket 的树形结构方案构建。路由器还添加了 SIMD 加速的路由参数解码和 JavaScriptCore 结构缓存,以充分发挥现代硬件的性能潜力。
基本设置
server.ts
Bun.serve() 中的路由会接收一个 BunRequest(继承自 Request),并返回一个 Response 或 Promise<Response>。由于路由使用这些 Request 和 Response 类型,因此发送和接收 HTTP 请求时可以更轻松地使用相同的代码。
异步路由
异步/等待
在路由处理函数中使用 async/await,以返回一个Promise<Response>。
Promise
你也可以直接从路由处理函数返回一个Promise<Response>。
路由优先级
Bun 按具体程度从高到低匹配路由:- 精确路由(
/users/all) - 参数路由(
/users/:id) - 通配符路由(
/users/*) - 全局捕获(
/*)
类型安全的路由参数
TypeScript 会解析以字符串字面量形式传入的路由参数,因此访问request.params 时,编辑器会显示自动补全。
index.ts
\uFFFD)。
静态响应
路由也可以是Response 对象(无需处理函数)。Bun.serve() 会针对零分配调度对其进行优化,非常适合健康检查、重定向和固定内容:
Response 对象,通常能提升至少 15% 的性能。
Bun 会在服务器对象的整个生命周期内缓存静态路由响应。要重新加载静态路由,请调用 server.reload(options)。
文件响应与静态响应的区别
从路由提供文件时,具体行为取决于你是将文件内容缓冲起来,还是直接提供文件:new Response(await file.bytes())) 会在启动时将内容缓冲至内存:
- 请求时无文件系统 I/O — 内容完全从内存服务
- 支持 ETag — 自动生成与验证缓存的 ETag
- 支持 If-None-Match — 客户端 ETag 匹配时返回
304 Not Modified - 无 404 处理 — 缺失文件在启动时报错,不在运行时 404
- 内存占用 — 文件内容全量存储于 RAM
- 适合用于:小型静态资源、API 响应、频繁访问的文件
new Response(Bun.file(path))) 每次请求从文件系统读取:
- 每次请求都会执行文件系统读取,检查文件存在并读取内容
- 内置 404 处理 — 若文件不存在或变得不可访问返回
404 Not Found - 支持 Last-Modified — 基于文件修改时间处理
If-Modified-Since头 - 支持 If-Modified-Since — 缓存有效时返回
304 Not Modified - 支持 范围请求 — 自动处理部分内容请求,返回
Content-Range头 - 支持流传输 — 使用带背压处理的缓冲读取器,实现高效内存使用
- 内存高效 — 只缓冲传输时的小块数据,不缓存整个文件
- 适合用于:大文件、动态内容、用户上传、频繁变更的文件
目录路由
若要在某个 URL 前缀下提供整个目录树,请将{ dir } 作为路由值传入。路由路径必须以 /* 结尾。
dir 打开该路径。对于非规范路径,Bun 会返回 404,因此实际提供的路径始终是路由器所匹配的路径。如果路径中包含 .、..、空片段、%2F,或将可直接出现在路径片段中的字符编码为 %XX 序列,则该路径为非规范路径。在 Linux 上,打开文件时会使用 openat2(RESOLVE_IN_ROOT),因此内核会限制符号链接,防止其指向 dir 之外。
路由区分大小写,但 macOS 和 Windows 上的文件系统默认不区分大小写。因此,大小写不同的 URL(
/static/Admin/secret.txt)会匹配目录通配符,而不是同级的 /static/admin/* 处理程序,并仍会打开 admin/secret.txt。与 nginx、Caddy 和其他静态文件服务器一样,应将受访问控制的内容放在 dir 之外,而不要依赖重叠路由来限制访问。- Content-Type 根据文件扩展名设置。
- 每个响应都会发送 Last-Modified 和弱 ETag(
W/"<size>-<mtime>"),并会根据If-Modified-Since/If-None-Match返回304 Not Modified。 - 支持 范围请求,并使用
Accept-Ranges: bytes和Content-Range。 - 请求解析到的目录若没有尾随
/,则会收到重定向到尾随斜杠 URL 的301响应。若 URL 有尾随斜杠,Bun 会从该目录提供index.html。 - 缺失文件会返回
404。
statCache: false 可禁用按路径缓存的 Last-Modified(每个路由可节省约 20 KB)。
流式传输文件
要流式传输文件,返回一个以BunFile 对象作为 body 的 Response。
⚡️ 速度 — Bun 会在可能的情况下自动使用
sendfile(2) 系统调用,
在内核级实现零拷贝文件传输—这是发送文件最快的方式。Bun.file 对象上使用 slice(start, end) 方法。Bun 会自动在 Response 对象上设置 Content-Range 和 Content-Length 标头。
fetch 请求处理器
fetch 处理器会处理未匹配任何路由的传入请求。它接收一个 Request 对象,并返回一个 Response 或 Promise<Response>。
fetch 处理器支持 async/await:
fetch 处理器还会将 Server 对象作为其第二个参数接收。