Serve
bun可以开启服务。用bun.serve开启。
const server = Bun.serve({
port: 8080, // defaults to $BUN_PORT, $PORT, $NODE_PORT otherwise 3000
// port: 0, // random port
hostname: "mydomain.com", // defaults to "0.0.0.0"
// `routes` requires Bun v1.2.3+
routes: {
// Static routes
"/api/status": new Response("OK"),
// Dynamic routes
"/users/:id": req => {
return new Response(`Hello User ${req.params.id}!`);
},
// Per-HTTP method handlers
"/api/posts": {
GET: () => new Response("List posts"),
POST: async req => {
const body = await req.json();
return Response.json({ created: true, ...body });
},
},
// Wildcard route for all routes that start with "/api/" and aren't otherwise matched
"/api/*": Response.json({ message: "Not found" }, { status: 404 }),
// Redirect from /blog/hello to /blog/hello/world
"/blog/hello": Response.redirect("/blog/hello/world"),
// Serve a file by lazily loading it into memory
"/favicon.ico": Bun.file("./favicon.ico"),
},
// (optional) fallback for unmatched routes:
// Required if Bun's version < 1.2.3
fetch(req) {
return new Response("Not Found", { status: 404 });
},
});
console.log(`Server running at ${server.url}`);
其他几种设置Port的方式
--portCLI
bun --port=4002 server.ts
BUN_PORT环境变量
BUN_PORT=4002 bun server.ts
PORT环境变量
PORT=4002 bun server.ts
NODE_PORT环境变量
NODE_PORT=4002 bun server.ts
HTTP/3 (QUIC)
实验性。可能会变动。
Bun.serve({
tls: {
key: Bun.file("./key.pem"),
cert: Bun.file("./cert.pem"),
},
http3: true,
fetch(req) {
return new Response("Hello over HTTP/3!");
},
});
启用http3后,服务器将在同一端口上同时通过TCP(HTTP/1.1)和UDP(HTTP/3)进行通信。HTTP/1.1响应中包含Alt-Svc头部信息,用于标识HTTP/3服务端点,使具备相应能力的客户端能够自动升级。
仅支持 HTTP/3(完全不使用 TCP 监听器)时,请设置 http1: false:
Bun.serve({
tls: {
key: Bun.file("./key.pem"),
cert: Bun.file("./cert.pem"),
},
http3: true,
http1: false, // 添加这行
fetch(req) {
return new Response("HTTP/3 only");
},
});
idleTimeout
连续x秒内无操作就关闭连接。默认是10秒。
要配置此选项,需设置 idleTimeout 字段(单位:秒)。最大值为255,当取值为0时会完全禁用超时功能。
Bun.serve({
// 30 seconds (default is 10)
idleTimeout: 30,
fetch(req) {
return new Response("Bun!");
},
});
导出默认配置
import type { Serve } from "bun";
export default {
fetch(req) {
return new Response("Bun!");
},
} satisfies Serve.Options<undefined>;
路由热重载
const server = Bun.serve({
routes: {
"/api/version": () => Response.json({ version: "1.0.0" }),
},
});
// Deploy new routes without downtime
server.reload({
routes: {
"/api/version": () => Response.json({ version: "2.0.0" }),
},
});
服务生命周期函数
- stop()、reload()
const server = Bun.serve({
fetch(req) {
return new Response("Hello!");
},
});
// Gracefully stop the server (waits for in-flight requests)
await server.stop();
// Force stop and close all active connections
await server.stop(true);
- ref() 和 unref()
控制服务器是否保持Bun进程运行
// Don't keep process alive if server is the only thing running
server.unref();
// Restore default behavior - keep process alive
server.ref();
- reload()
无需重启更新处理程序
const server = Bun.serve({
routes: {
"/api/version": Response.json({ version: "v1" }),
},
fetch(req) {
return new Response("v1");
},
});
// Update to new handler
server.reload({
routes: {
"/api/version": Response.json({ version: "v2" }),
},
fetch(req) {
return new Response("v2");
},
});
这种方法只能让 fetch、error、routes、websocket 更新。
单请求控制
const server = Bun.serve({
async fetch(req, server) {
// 将此请求的静默时间设置为最多60秒,而非默认的10秒
server.timeout(req, 60);
// 若发送主体所需时间超过60秒,请求将被中止
await req.text();
return new Response("Done!");
},
});
想让一个请求长期有效要用两参数的 timeout
Bun.serve({
routes: {
"/events": (req, server) => {
// 禁用此流式响应的空闲超时机制。
// 否则,若无字节传输,则连接将被关闭。
// 发送时间为 10 秒(默认值为 idleTimeout)。
server.timeout(req, 0);
return new Response(
async function* () {
yield "data: hello\n\n";
// 事件可能零星发生,且连接不会被断开
},
{ headers: { "Content-Type": "text/event-stream" } },
);
},
},
});
获得IP
const server = Bun.serve({
fetch(req, server) {
const address = server.requestIP(req);
if (address) {
return new Response(`Client IP: ${address.address}, Port: ${address.port}`);
}
return new Response("Unknown client");
},
});