Skip to main content

Overview

The HTTP Server modules from effect/unstable/http provide tools for building HTTP servers with routing, middleware, and request handling.

Creating a server

import { NodeHttpServer, NodeRuntime } from "@effect/platform-node"
import { Layer } from "effect"
import { HttpRouter, HttpServer } from "effect/unstable/http"
import { createServer } from "node:http"

const routes = HttpRouter.empty.pipe(
  HttpRouter.get("/health", HttpRouter.json({ status: "ok" }))
)

const server = HttpRouter.serve(routes).pipe(
  Layer.provide(NodeHttpServer.layer(createServer, { port: 3000 }))
)

Layer.launch(server).pipe(NodeRuntime.runMain)

Routing

Basic routes

const routes = HttpRouter.empty.pipe(
  HttpRouter.get("/", HttpRouter.text("Welcome")),
  HttpRouter.get("/users", HttpRouter.json(users)),
  HttpRouter.post("/users", createUserHandler)
)

Route parameters

const routes = HttpRouter.empty.pipe(
  HttpRouter.get("/users/:id", Effect.gen(function*() {
    const params = yield* HttpRouter.params
    const userId = params.id
    // Handle request
  }))
)

Mounting sub-routers

const apiRoutes = HttpRouter.empty.pipe(
  HttpRouter.get("/users", getUsersHandler),
  HttpRouter.post("/users", createUserHandler)
)

const routes = HttpRouter.empty.pipe(
  HttpRouter.mount("/api", apiRoutes)
)

Request handling

Accessing the request

const handler = Effect.gen(function*() {
  const request = yield* HttpServerRequest.HttpServerRequest
  const body = yield* request.json
  // Process request
})

Sending responses

// JSON response
const handler = HttpRouter.json({ message: "Success" })

// Text response
const handler = HttpRouter.text("Hello World")

// Custom response
const handler = Effect.succeed(
  HttpServerResponse.empty({ status: 201 })
)

Middleware

Creating middleware

const loggingMiddleware = HttpMiddleware.make((request, next) =>
  Effect.gen(function*() {
    yield* Effect.log(`${request.method} ${request.url}`)
    return yield* next(request)
  })
)

Applying middleware

const routes = HttpRouter.empty.pipe(
  HttpRouter.get("/users", getUsersHandler),
  HttpRouter.use(loggingMiddleware)
)

Platform support

Node.js

import { NodeHttpServer } from "@effect/platform-node"
import { createServer } from "node:http"

const serverLayer = NodeHttpServer.layer(createServer, { port: 3000 })

Bun

import { BunHttpServer } from "@effect/platform-bun"

const serverLayer = BunHttpServer.layer({ port: 3000 })

Web handler

Create a web handler for serverless environments:
const { handler, dispose } = HttpRouter.toWebHandler(
  routes.pipe(Layer.provide(HttpServer.layerServices))
)

// Use in serverless function
export default handler

See also

Build docs developers (and LLMs) love