Bun.serve() 的 routes 属性添加路由(静态路径、参数和通配符),或使用 fetch 方法处理未匹配的请求。
Bun.serve() 的路由器基于 uWebSocket 的树形方法,增加了 SIMD 加速的路由参数解码和 JavaScriptCore 结构缓存,以进一步突破现代硬件的性能极限。
基本设置
server.ts
Bun.serve() 中的路由接收一个 BunRequest(它扩展了 Request)并返回一个 Response 或 Promise<Response>。这使得在发送和接收 HTTP 请求时使用相同的代码变得更加容易。
异步路由
Async/await
在路由处理器中使用 async/await 来返回Promise<Response>。
Promise
你也可以从路由处理器中返回Promise<Response>。
路由优先级
路由按优先级顺序匹配:- 精确路由(
/users/all) - 参数路由(
/users/:id) - 通配符路由(
/users/*) - 全局捕获路由(
/*)
类型安全的路由参数
当路径作为字符串字面量传递时,TypeScript 会解析路由参数,因此在访问request.params 时编辑器会显示自动补全。
index.ts
\uFFFD)。
静态响应
路由也可以是Response 对象(无需处理器函数)。Bun.serve() 会对其进行零分配调度优化,适用于健康检查、重定向和固定内容:
Response 对象有 15% 的性能提升。
静态路由响应在服务器对象的生命周期内被缓存。要重新加载静态路由,请调用 server.reload(options)。
文件响应 vs 静态响应
从路由提供文件服务时,行为取决于你是将文件内容缓冲到内存中还是直接提供文件: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头部的部分内容请求 - 流式传输——使用支持背压的缓冲读取器,内存效率高
- 内存高效——传输期间仅缓冲小块数据,而非整个文件
- 最适合:大文件、动态内容、用户上传、频繁变化的文件
流式传输文件
要流式传输文件,返回一个以BunFile 对象作为主体的 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 对象作为其第二个参数接收。