new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

Deno · Fundamentals · all subjects

http_server

51 notes, read out of this brain and free to use. Each one was extracted from a source and is re-checked against its exam.

serveDir from @std/http for static files

Example of serving static files: ```ts import { serveDir } from "jsr:@std/http/file-server"; Deno.serve((req) => serveDir(req, { fsRoot: "./public" })); ``` The serveDir function handles content types, range requests, and directory traversal protection. Run with read access: deno run -N -R server.ts. It can also be used as a CLI: deno run -RN jsr:@std/http/file-server ./public

Deno.serve basic handler returns Response

The Deno.serve function takes a handler function that receives an incoming request and must return a Response or Promise<Response>. The handler can be a regular function or an async function.

Default port for Deno.serve is 8000

When using Deno.serve without specifying a port, it listens on port 8000 by default.

Deno.serve port and hostname options

Deno.serve accepts an options bag as the first or second argument. The port option sets the listening port. The hostname option sets the bind address, for example '0.0.0.0' to bind to all interfaces.

Hello World HTTP server example

Example of a basic HTTP server: ```ts Deno.serve((_req) => { return new Response("Hello, World!"); }); ``` This example shows the simplest HTTP server that returns the same response for every request.

Run server with --allow-net flag

To run an HTTP server, use the command: deno run --allow-net server.ts. The --allow-net flag grants network access permission required by Deno.serve.

Inspect request method, path, query params, headers, body

Example of extracting request details: ```ts Deno.serve(async (req) => { console.log("Method:", req.method); const url = new URL(req.url); console.log("Path:", url.pathname); console.log("Query parameters:", url.searchParams); console.log("Headers:", req.headers); if (req.body) { const body = await req.text(); console.log("Body:", body); } return new Response("Hello, World!"); }); ``` This shows how to access the HTTP method, URL pathname, query string parameters, headers, and request body from the incoming request.

Request body methods can fail on client disconnect

Calling req.text(), req.json(), req.formData(), req.arrayBuffer(), req.body.getReader().read(), or req.body.pipeTo() can fail if the user hangs up the connection before the body is fully received. Always handle these potential errors.

Response with status code, headers, and JSON body example

Example of returning a 404 response with JSON body and custom headers: ```ts Deno.serve((req) => { const body = JSON.stringify({ message: "NOT FOUND" }); return new Response(body, { status: 404, headers: { "content-type": "application/json; charset=utf-8", }, }); }); ```

Response streaming with ReadableStream

Example of a response that returns a stream of data: ```ts Deno.serve((req) => { let timer: number; const body = new ReadableStream({ async start(controller) { timer = setInterval(() => { controller.enqueue("Hello, World!\n"); }, 1000); }, cancel() { clearInterval(timer); }, }); return new Response(body.pipeThrough(new TextEncoderStream()), { headers: { "content-type": "text/plain; charset=utf-8", }, }); }); ``` The cancel function is called when the client hangs up the connection and must clean up resources.

Handle stream cancellation on client disconnect

When a client hangs up the connection, the response body stream is cancelled. The cancel function in a ReadableStream or errors in write() calls on a WritableStream must be handled, otherwise the server will keep queuing up messages and eventually run out of memory.

URLPattern for routing requests

Example of routing with URLPattern: ```ts const userPattern = new URLPattern({ pathname: "/users/:id" }); Deno.serve((req) => { const match = userPattern.exec(req.url); if (match) { const id = match.pathname.groups.id; return new Response(`User ${id}`); } if (new URL(req.url).pathname === "/") { return new Response("Home"); } return new Response("Not found", { status: 404 }); }); ``` URLPattern is a built-in web API for matching URL patterns.

Connection cannot be reused after WebSocket upgrade

The connection that a WebSocket was created on cannot be used for HTTP traffic after a WebSocket upgrade has been performed.

Graceful shutdown with Deno.serve return value

Example of graceful shutdown: ```ts const server = Deno.serve((_req) => new Response("Hello")); Deno.addSignalListener("SIGINT", async () => { console.log("shutting down"); await server.shutdown(); }); ``` Deno.serve returns an HttpServer object whose shutdown() method stops accepting new connections while letting in-flight requests finish. Combine with a signal listener for clean exits in production.

Use AbortSignal with Deno.serve signal option

Deno.serve accepts a signal option that can be an AbortSignal to tie the server's lifetime to other logic.

HTTPS support with cert and key options

Example of HTTPS server: ```ts Deno.serve({ port: 8443, cert: Deno.readTextFileSync("./cert.pem"), key: Deno.readTextFileSync("./key.pem"), }, (_req) => new Response("Hello over HTTPS!")); ``` The cert and key options take PEM-encoded certificate and private key contents as strings, not file paths. Run with: deno run --allow-net --allow-read=cert.pem,key.pem server.ts

Generate self-signed certificate with OpenSSL

Command to generate a short-lived self-signed certificate for local development: ```sh openssl req -x509 -newkey rsa:2048 -nodes -days 1 \ -keyout key.pem -out cert.pem \ -subj "/CN=localhost" \ -addext "subjectAltName=DNS:localhost" ```

HTTP/2 support is automatic

HTTP/2 support is automatic when using the HTTP server APIs with Deno. The server handles HTTP/1 or HTTP/2 requests seamlessly without any configuration. HTTP/2 is also supported over cleartext with prior knowledge.

Enable automatic response body compression

The HTTP server can automatically compress response bodies using gzip or brotli. Enable it for a single server with `automaticCompression: true` option, or for the whole process by setting the environment variable DENO_SERVE_AUTOMATIC_COMPRESSION=1.

Automatic compression conditions

A response body is compressed automatically if: the request has an Accept-Encoding header indicating support for br (Brotli) or gzip (Deno respects quality value preference), the response has a Content-Type considered compressible (derived from jshttp/mime-db), and the response body is greater than 64 bytes.

Automatic compression response headers

When a response body is compressed automatically, Deno sets the Content-Encoding header to reflect the encoding method and adjusts or adds the Vary header to indicate which request headers affected the response.

Prevent automatic compression with response headers

A response will not be compressed automatically if it contains: a Content-Encoding header (indicating encoding already done), a Content-Range header (indicating a range request), or a Cache-Control header with the no-transform value (indicating the server doesn't want Deno or downstream proxies to modify the response).

Deno.upgradeWebSocket for WebSocket support

Example of upgrading an HTTP request to WebSocket: ```ts Deno.serve((req) => { if (req.headers.get("upgrade") != "websocket") { return new Response(null, { status: 426 }); } const { socket, response } = Deno.upgradeWebSocket(req); socket.addEventListener("open", () => { console.log("a client connected!"); }); socket.addEventListener("message", (event) => { if (event.data === "ping") { socket.send("pong"); } }); return response; }); ``` The Deno.upgradeWebSocket function returns an object with a socket (WebSocket object) and a response to return to the incoming request.

WebSockets only supported on HTTP/1.1

WebSockets are only supported on HTTP/1.1 for now, not on HTTP/2.

Default fetch export for HTTP server

Example of creating an HTTP server with default fetch export: ```ts export default { fetch(request) { const userAgent = request.headers.get("user-agent") || "Unknown"; return new Response(`User Agent: ${userAgent}`); }, } satisfies Deno.ServeDefaultExport; ``` This file can be run with: deno serve server.ts. Add `satisfies Deno.ServeDefaultExport` for proper type-checking.

Request abort signal legacy behavior deprecation

For historical reasons, Deno.serve fires the abort event on a request's signal even when the handler returns successfully. This trips up some Node proxy libraries like http-proxy. Pass --unstable-no-legacy-abort to opt into corrected behavior where signal only aborts when the client actually disconnects. Relying on legacy behavior now prints a deprecation warning.

Automatic HTTP tracing with Deno.serve

When using Deno.serve to create an HTTP server, a span is automatically created for each incoming request. The span ends when response headers are sent (not when the response body is complete). The span name is ${method} and the span kind is 'server'.

Automatic HTTP tracing with fetch

When using fetch to make an HTTP request, a span is automatically created for the request. The span ends when response headers are received. The span name is ${method} and the span kind is 'client'.

Deno.serve span attributes for HTTP requests

For incoming HTTP requests with Deno.serve, the following attributes are automatically added to spans on creation: http.request.method, url.full, url.scheme, url.path, url.query. After the request is handled, http.response.status_code is added.

fetch span attributes for HTTP requests

For outgoing HTTP requests with fetch, the following attributes are automatically added to spans on creation: http.request.method, url.full, url.scheme, url.path, url.query. After the response is received, http.status_code is added.

HTTP server request duration metric

The metric http.server.request.duration is a histogram measuring the duration of incoming HTTP requests served with Deno.serve or Deno.serveHttp, from when the request is received to when response headers are sent. Unit is seconds. Histogram buckets are [0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1.0, 2.5, 5.0, 7.5, 10.0].

HTTP server request duration metric attributes

The http.server.request.duration metric includes these attributes: http.request.method, url.scheme, network.protocol.version, server.address, server.port, http.response.status_code (if no fatal error), and error.type (if error occurred).

HTTP server active requests metric

The metric http.server.active_requests is a gauge measuring the number of active requests being handled by Deno.serve or Deno.serveHttp at any given time. It counts requests that have been received but not yet responded to (response headers not yet sent).

HTTP server active requests metric attributes

The http.server.active_requests metric includes these attributes: http.request.method, url.scheme, server.address, server.port.

HTTP server response body size metric

The metric http.server.response.body.size is a histogram measuring the size of response bodies of incoming HTTP requests served with Deno.serve or Deno.serveHttp. Unit is bytes. Histogram buckets are [0, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000].

OpenTelemetry propagation with fetch and Deno.serve

The W3C Trace Context and W3C Baggage propagators automatically work with Deno's fetch API and Deno.serve, enabling end-to-end tracing across HTTP requests without manual context management.

Example: Add route attribute to HTTP span with Deno.serve

import { trace } from "npm:@opentelemetry/api@1"; const INDEX_ROUTE = new URLPattern({ pathname: "/" }); const BOOK_ROUTE = new URLPattern({ pathname: "/book/:id" }); Deno.serve(async (req) => { const span = trace.getActiveSpan(); if (INDEX_ROUTE.test(req.url)) { span.setAttribute("http.route", "/"); span.updateName(`${req.method} /`); // handle index route } else if (BOOK_ROUTE.test(req.url)) { span.setAttribute("http.route", "/book/:id"); span.updateName(`${req.method} /book/:id`); // handle book route } else { return new Response("Not found", { status: 404 }); } }); This example shows how to manually add http.route attributes and update span names for HTTP handlers.

Next.js setup with Deno

To create a new Next.js app with Deno, run: deno run -A npm:create-next-app@latest my-next-app, then cd my-next-app, then deno task dev. The app opens at http://localhost:3000. TypeScript is included by default. Edit page.tsx to see changes live.

HTTP server example with Deno and Fresh

To get started with a Fresh app, run the command: deno run -Ar jsr:@fresh/init, then cd my-fresh-app, then deno task dev. This creates a new Fresh app and runs it with Deno. The app opens in the browser at http://localhost:8000. Edit /routes/index.tsx to see changes live.

Astro static site generator with Deno

To create a new Astro site with Deno, run: deno run -A npm:create-astro my-astro-site, then cd my-astro-site, then deno task dev. The site opens at http://localhost:4321. Edit /src/pages/index.astro to see changes live.

Vite setup with Deno

To create a new Vite app with Deno, run: deno run -A npm:create-vite@latest, then cd my-vite-app, then deno install, then deno task dev.

Lume static site generator setup with Deno

To create a new Lume site with Deno, run: mkdir my-lume-site, cd my-lume-site, then deno run -A https://lume.land/init.ts, then deno task serve.

Docusaurus setup with Deno

To create a new Docusaurus site with Deno, run: deno run -A npm:create-docusaurus@latest my-website classic, then cd my-website, then deno task start.

Hono web framework setup with Deno

To create a new Hono app with Deno, run: deno run -A npm:create-hono@latest, then cd my-hono-app, then deno task start. The app opens at http://localhost:8000.

Oak middleware framework HTTP server example

Oak is a middleware framework for handling HTTP with Deno. To create a basic server, create a file called server.ts with: import { Application } from "jsr:@oak/oak/application"; import { Router } from "jsr:@oak/oak/router"; const router = new Router(); router.get("/", (ctx) => { ctx.response.body = `<!DOCTYPE html><html><head><title>Hello oak!</title><head><body><h1>Hello oak!</h1></body></html>`; }); const app = new Application(); const port = 8080; app.use(router.routes()); app.use(router.allowedMethods()); console.log(`Server running on http://localhost:${port}`); app.listen({ port: port }); Run it with: deno run --allow-net server.ts

Fresh framework sends no JavaScript to clients by default

Fresh is the most popular web framework for Deno. It uses a model where no JavaScript is sent to clients by default. Fresh does most of its rendering on the server, with the client only responsible for re-rendering small islands of interactivity. Developers explicitly opt in to client-side rendering for specific components.

Astro is a static site generator for fast, lightweight websites

Astro is a static site generator that allows developers to create fast and lightweight websites.

Oak framework offers router, JSON parser, middlewares, and plugins

Oak is a middleware framework for handling HTTP with Deno. Oak offers additional functionality over the native Deno HTTP server, including a basic router, JSON parser, middlewares, and plugins.

Deno KV HTTP server example with Deno.serve

Here is an example of creating an HTTP server with Deno KV: const kv = await Deno.openKv(); Deno.serve(async () => { const res = await kv.get<number>(["requests"]); const requests = res.value + 1; await kv.set(["requests"], requests); return new Response(JSON.stringify(requests)); });

Deno.serve basic HTTP server example

To create a basic HTTP server with Deno.serve, pass a handler function that receives a request and returns a Response. Example: Deno.serve((_req) => { return new Response("Hello, World!"); }); By default, Deno.serve listens on port 8000, but this can be changed by passing a port number in an options bag as the first or second argument.

Deno HTTP Server APIs: Deno.serve vs Deno.serveHttp

Deno has two HTTP Server APIs: Deno.serve is a native, higher-level API that supports HTTP/1.1 and HTTP2 and is the preferred API to write HTTP servers in Deno. Deno.serveHttp is a native, low-level API that supports HTTP/1.1 and HTTP2.

Give your agent this brain