aboutsummaryrefslogtreecommitdiff
path: root/docs/api/http.md
diff options
context:
space:
mode:
authorGravatar Colin McDonnell <colinmcd94@gmail.com> 2023-02-23 17:13:30 -0800
committerGravatar GitHub <noreply@github.com> 2023-02-23 17:13:30 -0800
commitf54300578b1edc7f67daddbfae29575cbf305264 (patch)
tree1437f3274122c011f879dca71f59a74d75a33fd0 /docs/api/http.md
parent5929daeeae1f528abab31979a0a28bc87a03b1f4 (diff)
downloadbun-f54300578b1edc7f67daddbfae29575cbf305264.tar.gz
bun-f54300578b1edc7f67daddbfae29575cbf305264.tar.zst
bun-f54300578b1edc7f67daddbfae29575cbf305264.zip
Add documentation (#2148)bun-v0.5.7
* Add documentation * Tweaks * Fixes * Rearrange * Update
Diffstat (limited to 'docs/api/http.md')
-rw-r--r--docs/api/http.md257
1 files changed, 257 insertions, 0 deletions
diff --git a/docs/api/http.md b/docs/api/http.md
new file mode 100644
index 000000000..d05691556
--- /dev/null
+++ b/docs/api/http.md
@@ -0,0 +1,257 @@
+{% callout %}
+**Note** — Bun provides an [almost complete](/docs/runtime/nodejs#node_http) implementation of the Node.js [`http`](https://nodejs.org/api/http.html) and [`https`](https://nodejs.org/api/https.html) modules. This page only documents Bun-native APIs.
+{% /callout %}
+
+## Start a server
+
+`Bun.serve(options) => Server`
+
+Start an HTTP server in Bun with `Bun.serve`.
+
+```ts
+Bun.serve({
+ fetch(req) {
+ return new Response(`Bun!`);
+ },
+});
+```
+
+The `fetch` handler handles incoming requests. It receives a [`Request`](https://developer.mozilla.org/en-US/docs/Web/API/Request) object and returns a [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response) or `Promise<Response>`.
+
+```ts
+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!`);
+ },
+});
+```
+
+To configure which port and hostname the server will listen on:
+
+```ts
+Bun.serve({
+ port: 8080, // defaults to $PORT, then 3000
+ hostname: "mydomain.com", // defaults to "0.0.0.0"
+ fetch(req) {
+ return new Response(`404!`);
+ },
+});
+```
+
+## Error handling
+
+To activate development mode, set `development: true`. By default, development mode is _enabled_ unless `NODE_ENV` is `production`.
+
+```ts
+Bun.serve({
+ development: true,
+ fetch(req) {
+ throw new Error("woops!");
+ },
+});
+```
+
+In development mode, Bun will surface errors in-browser with a built-in error page.
+
+{% image src="/images/exception_page.png" caption="Bun's built-in 500 page" /%}
+
+To handle server-side errors, implement an `error` handler. This function should return a `Response` to served to the client when an error occurs. This response will supercede Bun's default error page in `development` mode.
+
+```ts
+Bun.serve({
+ fetch(req) {
+ throw new Error("woops!");
+ },
+ error(error: Error) {
+ return new Response(`<pre>${error}\n${error.stack}</pre>`, {
+ headers: {
+ "Content-Type": "text/html",
+ },
+ });
+ },
+});
+```
+
+{% callout %}
+**Note** — Full debugger support is planned.
+{% /callout %}
+
+The call to `Bun.serve` returns a `Server` object. To stop the server, call the `.stop()` method.
+
+```ts
+const server = Bun.serve({
+ fetch() {
+ return new Response("Bun!");
+ },
+});
+
+server.stop();
+```
+
+## TLS
+
+Bun supports TLS out of the box, powered by [OpenSSL](https://www.openssl.org/). Enable TLS by passing in a value for `keyFile` and `certFile`; both are required to enable TLS. If needed, supply a `passphrase` to decrypt the `keyFile`.
+
+```ts
+Bun.serve({
+ fetch(req) {
+ return new Response("Hello!!!");
+ },
+ keyFile: "./key.pem", // path to TLS key
+ certFile: "./cert.pem", // path to TLS cert
+ passphrase: "super-secret", // optional passphrase
+});
+```
+
+The root CA and Diffie-Helman parameters can be configured as well.
+
+```ts
+Bun.serve({
+ fetch(req) {
+ return new Response("Hello!!!");
+ },
+ keyFile: "./key.pem", // path to TLS key
+ certFile: "./cert.pem", // path to TLS cert
+ caFile: "./ca.pem", // path to root CA certificate
+ dhParamsFile: "./dhparams.pem", // Diffie Helman parameters
+});
+```
+
+## Hot reloading
+
+Thus far, the examples on this page have used the explicit `Bun.serve` API. Bun also supports an alternate syntax.
+
+```ts#server.ts
+export default {
+ fetch(req) {
+ return new Response(`Bun!`);
+ },
+};
+```
+
+Instead of passing the server options into `Bun.serve`, export it. This file can be executed as-is; when Bun runs a file with a `default` export containing a `fetch` handler, it passes it into `Bun.serve` under the hood.
+
+This syntax has one major advantage: it is hot-reloadable out of the box. When any source file is changed, Bun will reload the server with the updated code _without restarting the process_. This makes hot reloads nearly instantaneous. Use the `--hot` flag when starting the server to enable hot reloading.
+
+```bash
+$ bun --hot server.ts
+```
+
+It's possible to configure hot reloading while using the explicit `Bun.serve` API; for details refer to [Runtime > Hot reloading](/docs/runtime/hot).
+
+## Streaming files
+
+To stream a file, return a `Response` object with a `BunFile` object as the body.
+
+```ts
+import { serve, file } from "bun";
+
+serve({
+ fetch(req) {
+ return new Response(Bun.file("./hello.txt"));
+ },
+});
+```
+
+{% callout %}
+⚡️ **Speed** — Bun automatically uses the [`sendfile(2)`](https://man7.org/linux/man-pages/man2/sendfile.2.html) system call when possible, enabling zero-copy file transfers in the kernel—the fastest way to send files.
+{% /callout %}
+
+**[v0.3.0+]** You can send part of a file using the [`slice(start, end)`](https://developer.mozilla.org/en-US/docs/Web/API/Blob/slice) method on the `Bun.file` object. This automatically sets the `Content-Range` and `Content-Length` headers on the `Response` object.
+
+```ts
+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));
+ },
+});
+```
+
+## Benchmarks
+
+Below are Bun and Node.js implementations of a simple HTTP server that responds `Bun!` to each incoming `Request`.
+
+{% codetabs %}
+
+```ts#Bun
+Bun.serve({
+ fetch(req: Request) {
+ return new Response(`Bun!`);
+ },
+ port: 3000,
+});
+```
+
+```ts#Node
+require("http")
+ .createServer((req, res) => res.end("Bun!"))
+ .listen(8080);
+```
+
+{% /codetabs %}
+The `Bun.serve` server can handle roughly 2.5x more requests per second than Node.js on Linux.
+
+{% table %}
+
+- Runtime
+- Requests per second
+
+---
+
+- Node 16
+- ~64,000
+
+---
+
+- Bun
+- ~160,000
+
+{% /table %}
+
+{% image width="499" alt="image" src="https://user-images.githubusercontent.com/709451/162389032-fc302444-9d03-46be-ba87-c12bd8ce89a0.png" /%}
+
+## Reference
+
+{% details summary="See TypeScript definitions" %}
+
+```ts
+interface Bun {
+ serve(options: {
+ fetch: (req: Request, server: Server) => Response | Promise<Response>;
+ hostname?: string;
+ port?: number;
+ development?: boolean;
+ error?: (error: Error) => Response | Promise<Response>;
+ keyFile?: string;
+ certFile?: string;
+ caFile?: string;
+ dhParamsFile?: string;
+ passphrase?: string;
+ maxRequestBodySize?: number;
+ lowMemoryMode?: boolean;
+ }): Server;
+}
+
+interface Server {
+ development: boolean;
+ hostname: string;
+ port: number;
+ pendingRequests: number;
+ stop(): void;
+}
+```
+
+{% /details %}