Bun

HTTP 伺服器

此頁面主要記錄 Bun 原生的 Bun.serve API。Bun 也實作了 fetch 和 Node.js 的 httphttps 模組。

這些模組已重新實作,以使用 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 物件,並傳回一個 ResponsePromise<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_ENVproduction

Bun.serve({
  development: true,
  fetch(req) {
    throw new Error("woops!");
  },
});

在開發模式下,Bun 會在瀏覽器中顯示內建錯誤頁面中的錯誤。

Bun 的內建 500 頁面

若要處理伺服器端錯誤,請實作 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 提供技術支援。傳入 keycert 的值以啟用 TLS;兩者都是啟用 TLS 所必需的。

Bun.serve({
  fetch(req) {
    return new Response("Hello!!!");
  },

  tls: {
    key: Bun.file("./key.pem"),
    cert: Bun.file("./cert.pem"),
  }
});

keycert 欄位預期會收到 TLS 金鑰和憑證的內容而不是路徑。這可以是字串、BunFileTypedArrayBuffer

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 也支援替代語法。

server.ts
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-RangeContent-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 伺服器的範例,它會對每個傳入的「要求」回應「Bun!」

Bun
Node
Bun
Bun.serve({
  fetch(req: Request) {
    return new Response("Bun!");
  },
  port: 3000,
});
Node
require("http")
  .createServer((req, res) => res.end("Bun!"))
  .listen(8080);

在 Linux 上,Bun.serve 伺服器每秒可以處理比 Node.js 多約 2.5 倍的請求。

執行時間每秒請求數
Node 16~64,000
Bun~160,000
image

參考

查看 TypeScript 定義