本页面主要记录 Bun 原生 Bun.serve
API。Bun 还实现了 fetch
以及 Node.js http
和 https
模块。
这些模块已重新实现,以使用 Bun 的快速内部 HTTP 基础设施。您可以直接使用这些模块;依赖这些模块的框架(如 Express)应开箱即用。有关粒度兼容性信息,请参阅 运行时 > Node.js API。
要使用干净的 API 启动高性能 HTTP 服务器,建议的方法是 Bun.serve
。
Bun.serve()
使用 Bun.serve
在 Bun 中启动 HTTP 服务器。
Bun.serve({
fetch(req) {
return new Response("Bun!");
},
});
fetch
处理程序处理传入请求。它接收一个 Request
对象,并返回一个 Response
或 Promise<Response>
。
Bun.serve({
fetch(req) {
const url = new URL(req.url);
if (url.pathname === "/") return new Response("Home page!");
if (url.pathname === "/blog") return new Response("Blog!");
return new Response("404!");
},
});
要配置服务器将侦听的端口和主机名
Bun.serve({
port: 8080, // defaults to $BUN_PORT, $PORT, $NODE_PORT otherwise 3000
hostname: "mydomain.com", // defaults to "0.0.0.0"
fetch(req) {
return new Response("404!");
},
});
要在 Unix 域套接字 上侦听
Bun.serve({
unix: "/tmp/my-socket.sock", // path to socket
fetch(req) {
return new Response(`404!`);
},
});
错误处理
要激活开发模式,请设置 development: true
。默认情况下,开发模式处于启用状态,除非 NODE_ENV
为 production
。
Bun.serve({
development: true,
fetch(req) {
throw new Error("woops!");
},
});
在开发模式下,Bun 将使用内置错误页面在浏览器中显示错误。
要处理服务器端错误,请实现一个 error
处理程序。当发生错误时,此函数应返回一个 Response
以提供给客户端。此响应将取代 development
模式下的 Bun 默认错误页面。
Bun.serve({
fetch(req) {
throw new Error("woops!");
},
error(error) {
return new Response(`<pre>${error}\n${error.stack}</pre>`, {
headers: {
"Content-Type": "text/html",
},
});
},
});
对 Bun.serve
的调用返回一个 Server
对象。要停止服务器,请调用 .stop()
方法。
const server = Bun.serve({
fetch() {
return new Response("Bun!");
},
});
server.stop();
TLS
Bun 开箱即用支持 TLS,由 BoringSSL 提供支持。通过传入 key
和 cert
的值来启用 TLS;启用 TLS 需要同时提供这两个值。
Bun.serve({
fetch(req) {
return new Response("Hello!!!");
},
tls: {
key: Bun.file("./key.pem"),
cert: Bun.file("./cert.pem"),
}
});
key
和 cert
字段需要 TLS 密钥和证书的内容,而不是其路径。它可以是字符串、BunFile
、TypedArray
或 Buffer
。
Bun.serve({
fetch() {},
tls: {
// BunFile
key: Bun.file("./key.pem"),
// Buffer
key: fs.readFileSync("./key.pem"),
// string
key: fs.readFileSync("./key.pem", "utf8"),
// array of above
key: [Bun.file("./key1.pem"), Bun.file("./key2.pem")],
},
});
如果您的私钥使用密码加密,请提供 passphrase
值以对其进行解密。
Bun.serve({
fetch(req) {
return new Response("Hello!!!");
},
tls: {
key: Bun.file("./key.pem"),
cert: Bun.file("./cert.pem"),
passphrase: "my-secret-passphrase",
}
});
或者,你可以通过传递 ca
的值来覆盖受信任的 CA 证书。默认情况下,服务器将信任 Mozilla 策划的众所周知的 CA 列表。当指定 ca
时,Mozilla 列表将被覆盖。
Bun.serve({
fetch(req) {
return new Response("Hello!!!");
},
tls: {
key: Bun.file("./key.pem"), // path to TLS key
cert: Bun.file("./cert.pem"), // path to TLS cert
ca: Bun.file("./ca.pem"), // path to root CA certificate
}
});
要覆盖 Diffie-Hellman 参数
Bun.serve({
// ...
tls: {
// other config
dhParamsFile: "/path/to/dhparams.pem", // path to Diffie Hellman parameters
},
});
对象语法
到目前为止,本页上的示例都使用了显式的 Bun.serve
API。Bun 还支持备用语法。
import {type Serve} from "bun";
export default {
fetch(req) {
return new Response("Bun!");
},
} satisfies Serve;
不要将服务器选项传递到 Bun.serve
,而是 export default
它。此文件可以按原样执行;当 Bun 看到一个包含 fetch
处理程序的 default
导出的文件时,它会在后台将其传递到 Bun.serve
中。
流式传输文件
要流式传输文件,请返回一个 Response
对象,其中 BunFile
对象作为主体。
Bun.serve({
fetch(req) {
return new Response(Bun.file("./hello.txt"));
},
});
⚡️ 速度 — Bun 在可能的情况下自动使用 sendfile(2)
系统调用,从而在内核中启用零拷贝文件传输,这是发送文件的最快方式。
你可以使用 Bun.file
对象上的 slice(start, end)
方法发送文件的一部分。这会自动在 Response
对象上设置 Content-Range
和 Content-Length
头。
Bun.serve({
fetch(req) {
// parse `Range` header
const [start = 0, end = Infinity] = req.headers
.get("Range") // Range: bytes=0-100
.split("=") // ["Range: bytes", "0-100"]
.at(-1) // "0-100"
.split("-") // ["0", "100"]
.map(Number); // [0, 100]
// return a slice of the file
const bigFile = Bun.file("./big-video.mp4");
return new Response(bigFile.slice(start, end));
},
});
基准
以下是 Bun 和 Node.js 实现的一个简单 HTTP 服务器,它对每个传入的 Request
响应 Bun!
。
Bun.serve({
fetch(req: Request) {
return new Response("Bun!");
},
port: 3000,
});
require("http")
.createServer((req, res) => res.end("Bun!"))
.listen(8080);
Bun.serve
服务器在 Linux 上每秒可以处理大约比 Node.js 多 2.5 倍的请求。
运行时 | 每秒请求数 |
---|---|
Node 16 | ~64,000 |
Bun | ~160,000 |
参考
查看 TypeScript 定义