HttpRouter
Builds server-side routers for Effect HTTP applications.
HttpRouter collects routes and middleware while an application layer is being built. Once the router is complete, it handles each HttpServerRequest by finding a matching route and producing an HttpServerResponse. The module also includes helpers for route definitions, prefixes, parameters, request decoding, CORS, and running the router.
Constructors
Converting
toHttpEffect
Builds an application layer with a router and returns the router as an HTTP handler effect.
Details
The returned effect handles the current HttpServerRequest in the current Scope; route request markers are converted into the ordinary requirements of the returned handler.
Signature
declare function toHttpEffect<A, E, R>(
appLayer: Layer<A, E, R>,
): Effect<
Effect<
HttpServerResponse,
HttpServerError | Only<"Error", R> | Only<"GlobalRequires", R>,
Scope | HttpServerRequest | Only<"GlobalRequires", R> | Only<"Requires", R>
>,
Without<E>,
Scope | Exclude<Without<R>, HttpRouter>
>;toWebHandler
Builds a Fetch-compatible request handler from an HTTP router application layer.
Details
The result contains a handler function that converts Web Request values to Web Response values and a dispose function for releasing the layer resources.
Signature
declare function toWebHandler<
A,
E,
R extends
| HttpRouter
| Request<"Requires", any>
| Request<"Error", any>
| Request<"GlobalRequires", any>
| Request<"GlobalError", any>,
HE,
HR = Exclude<Only<"Requires", R>, A> | Exclude<Only<"GlobalRequires", R>, A>,
ReqR = Exclude<HR, Scope | HttpServerRequest | A>,
>(
appLayer: Layer<A, E, R>,
options?: {
readonly disableLogger?: boolean;
readonly memoMap?: MemoMap;
readonly middleware?: (
effect: Effect<
HttpServerResponse,
HttpServerError | Only<"Error", R> | Only<"GlobalError", R>,
Scope | HttpServerRequest | Only<"Requires", R> | Only<"GlobalRequires", R>
>,
) => Effect<HttpServerResponse, HE, GlobalProvided | HR>;
readonly routerConfig?: Partial<RouterConfig>;
},
): {
readonly dispose: () => Promise<void>;
readonly handler: [ReqR] extends [never]
? (request: Request, context?: Context<never>) => Promise<Response>
: (request: Request, context: Context<ReqR>) => Promise<Response>;
};Getters
Layers
Create a layer that adds a single route to the HTTP router.
Signature
declare function add<E = never, R = never>(method: "GET" | "POST" | "PATCH" | "PUT" | "DELETE" | "OPTIONS" | "*", path: PathInput, handler: HttpServerResponse | Effect<HttpServerResponse, E, R> | (request: HttpServerRequest) => Effect<HttpServerResponse, E, R>, options?: {
readonly uninterruptible?: boolean;
}): Layer<never, never, HttpRouter | From<"Requires", Exclude<R, Provided>> | From<"Error", E>>Create a layer that adds multiple routes to the HTTP router.
Signature
declare function addAll<Routes extends readonly Array<Route<any, any>>, EX = never, RX = never>(routes: Routes | Effect<Routes, EX, RX>, options?: {
readonly prefix?: string;
}): Layer<never, EX, HttpRouter | Exclude<RX, Scope> | From<"Requires", Exclude<Context<Routes[number]>, Provided>> | From<"Error", Error<Routes[number]>>>Middleware that applies CORS headers to the HTTP response.
Signature
declare function cors(options?: {
readonly allowedHeaders?: readonly Array<string>;
readonly allowedMethods?: readonly Array<string>;
readonly allowedOrigins?: readonly Array<string>;
readonly credentials?: boolean;
readonly exposedHeaders?: readonly Array<string>;
readonly maxAge?: number;
}): Layer<never, never, HttpRouter>disableLogger
Middleware that disables the logger for some routes.
Signature
declare const disableLogger: Layer.Layer<never>;Layer that provides a newly constructed HttpRouter.
Signature
declare const layer: Layer.Layer<HttpRouter>;provideRequest
Provides request-level dependencies to some routes.
Signature
declare function provideRequest<A2, E2, R2>(
layer: Layer<A2, E2, R2>,
): <A, E, R>(self: Layer<A, E, R>) => Layer<A, E2 | E, R2 | Exclude<R, From<"Requires", A2>>>;Runs the provided application layer as an HTTP server.
Signature
declare function serve<A, E, R, HE, HR = Only<"Requires", R> | Only<"GlobalRequires", R>>(
appLayer: Layer<A, E, R>,
options?: {
readonly disableListenLog?: boolean;
readonly disableLogger?: boolean;
readonly middleware?: (
effect: Effect<
HttpServerResponse,
HttpServerError | Only<"Error", R> | Only<"GlobalError", R>,
Scope | HttpServerRequest | Only<"Requires", R> | Only<"GlobalRequires", R>
>,
) => Effect<HttpServerResponse, HE, HR>;
readonly routerConfig?: Partial<RouterConfig>;
},
): Layer<
A,
Without<E>,
HttpServer | Exclude<Without<R>, HttpRouter> | Exclude<Exclude<HR, GlobalProvided>, HttpRouter>
>;Creates a layer that accesses the current HttpRouter service and runs the supplied effect.
When to use
Use when you need to register routes or middleware with the router during layer construction.
Signature
declare function use<A, E, R>(
f: (router: HttpRouter) => Effect<A, E, R>,
): Layer<never, E, HttpRouter | Exclude<R, Scope>>;Middleware
middleware
Create a middleware layer that can be used to modify requests and responses.
Details
By default, the middleware only affects the routes that it is provided to.
If you want to create a middleware that applies globally to all routes, pass the global option as true.
Signature
declare const middleware: middleware.Make<never, never> & <Config extends {
handles?: any;
provides?: any;
} = {}>() => middleware.Make<Config extends {
provides: infer R;
} ? R : never, Config extends {
handles: infer E;
} ? E : never>Middleware interface
Composable descriptor for route-scoped HTTP router middleware.
Details
Its layer can be provided to route layers, and combine composes middleware while tracking provided services, handled errors, and remaining requirements at the type level.
Signature
interface Middleware<
Config extends {
error: any;
handles: any;
layerError: any;
layerRequires: any;
provides: any;
requires: any;
},
> {
readonly "~effect/http/HttpRouter/Middleware": Config;
readonly combine: <
Config2 extends {
error: any;
handles: any;
layerError: any;
layerRequires: any;
provides: any;
requires: any;
},
>(
other: Middleware<Config2>,
) => Middleware<{
error: Config2["error"] | Exclude<Config["error"], Config2["handles"]>;
handles: Config2["handles"] | Config["handles"];
layerError: Config["layerError"] | Config2["layerError"];
layerRequires: Config["layerRequires"] | Config2["layerRequires"];
provides: Config["provides"] | Config2["provides"];
requires: Exclude<Config["requires"], Config2["provides"]> | Config2["requires"];
}>;
readonly layer: [Config["requires"]] extends [never]
? Layer<
From<"Requires", Config["provides"]>,
Config["layerError"],
Config["layerRequires"] | From<"Requires", any[any]> | From<"Error", Config["error"]>
>
: "Need to .combine(middleware) that satisfy the missing request dependencies";
}Models
Other
middleware
Types used by the middleware constructor.
Helper types for request-level dependency markers used by router layers and middleware.
Helper types for extracting the error and context types carried by Route values.
Routes
prefixRoute
Returns a copy of a route with its path prefixed.
Details
The prefix is also tracked on the route so that, when the route handles a request, the matched prefix can be removed from the request URL seen by the handler.
Signature
declare const prefixRoute: {
(prefix: string): <E, R>(self: Route<E, R>) => Route<E, R>;
<E, R>(self: Route<E, R>, prefix: string): Route<E, R>;
};Constructs a Route from an HTTP method, path, and handler.
Details
The handler may be a static response, an effect that produces a response, or a function from the current request to a response effect. Set uninterruptible to prevent the route handler from being made interruptible while it runs.
Signature
declare function route<E = never, R = never>(method: "*" | HttpMethod, path: PathInput, handler: HttpServerResponse | Effect<HttpServerResponse, E, R> | (request: HttpServerRequest) => Effect<HttpServerResponse, E, R>, options?: {
readonly uninterruptible?: boolean;
}): Route<E, Exclude<R, Provided>>Description of a registered HTTP route.
Details
A route pairs an HTTP method and path pattern with a response handler, plus metadata used for prefix handling and interruptibility.
Signature
interface Route<E = never, R = never> {
readonly "~effect/http/HttpRouter/Route": "~effect/http/HttpRouter/Route";
readonly handler: Effect<HttpServerResponse, E, R>;
readonly method: "*" | HttpMethod;
readonly path: PathInput;
readonly prefix: Option<string>;
readonly uninterruptible: boolean;
}Schemas
schemaJson
Decodes a schema from the current request and its JSON body.
Details
The input passed to the schema includes the request method, URL, headers, cookies, path parameters, search parameters, and parsed JSON body. The effect fails if the body cannot be parsed or the schema decode fails.
Signature
declare function schemaJson<
A,
I extends Partial<{
readonly body: any;
readonly cookies: Readonly<Record<string, string | undefined>>;
readonly headers: Readonly<Record<string, string | undefined>>;
readonly method: HttpMethod;
readonly pathParams: Readonly<Record<string, string | undefined>>;
readonly searchParams: Readonly<Record<string, string | ReadonlyArray<string> | undefined>>;
readonly url: string;
}>,
RD,
>(
schema: ConstraintCodec<A, I, RD, unknown>,
options?: ParseOptions,
): Effect<
A,
SchemaError | HttpServerError,
HttpServerRequest | ParsedSearchParams | RouteContext | RD
>;schemaNoBody
Decodes a schema from the current request without reading the request body.
Details
The input passed to the schema includes the request method, URL, headers, cookies, path parameters, and search parameters.
Signature
declare function schemaNoBody<
A,
I extends Partial<{
readonly cookies: Readonly<Record<string, string | undefined>>;
readonly headers: Readonly<Record<string, string | undefined>>;
readonly method: HttpMethod;
readonly pathParams: Readonly<Record<string, string | undefined>>;
readonly searchParams: Readonly<Record<string, string | ReadonlyArray<string> | undefined>>;
readonly url: string;
}>,
RD,
>(
schema: ConstraintCodec<A, I, RD, unknown>,
options?: ParseOptions,
): Effect<A, SchemaError, HttpServerRequest | ParsedSearchParams | RouteContext | RD>;schemaParams
Decodes a schema from the current route path parameters and search parameters.
Details
When the same key appears in both sources, the path parameter value is used.
Signature
declare function schemaParams<A, I extends Readonly<Record<string, string | readonly Array<string> | undefined>>, RD>(schema: ConstraintCodec<A, I, RD, unknown>, options?: ParseOptions): Effect<A, SchemaError, ParsedSearchParams | RouteContext | RD>schemaPathParams
Decodes a schema from the path parameters captured for the current matched route.
Signature
declare function schemaPathParams<A, I extends Readonly<Record<string, string | undefined>>, RD>(
schema: ConstraintCodec<A, I, RD, unknown>,
options?: ParseOptions,
): Effect<A, SchemaError, RouteContext | RD>;Services
HttpRouter
Service tag for the HTTP router used while constructing an HTTP application. Route and middleware layers require this service to register themselves with the router.
Signature
declare const HttpRouter: Service<HttpRouter, HttpRouter>;HttpRouter interface
Defines the service interface for registering HTTP routes and middleware.
Details
An HttpRouter can add routes, apply path prefixes, install global middleware, and expose the registered routes as an Effect that handles the current server request.
Signature
interface HttpRouter {
readonly "~effect/http/HttpRouter": "~effect/http/HttpRouter";
readonly add: <E = never, R = never>(method: "GET" | "POST" | "PATCH" | "PUT" | "DELETE" | "OPTIONS" | "*", path: PathInput, handler: HttpServerResponse | Effect<HttpServerResponse, E, R> | (request: HttpServerRequest) => Effect<HttpServerResponse, E, R>, options?: {
readonly uninterruptible?: boolean;
}) => Effect<void, never, From<"Requires", Exclude<R, Provided>> | From<"Error", E>>;
readonly addAll: <Routes extends readonly Array<Route<any, any>>>(routes: Routes) => Effect<void, never, From<"Requires", Exclude<Context<Routes[number]>, Provided>> | From<"Error", Error<Routes[number]>>>;
readonly addGlobalMiddleware: <E, R>(middleware: (effect: Effect<HttpServerResponse, unhandled>) => Effect<HttpServerResponse, E, R> & unhandled extends E ? unknown : "You cannot handle any errors") => Effect<void, never, From<"GlobalRequires", Exclude<R, GlobalProvided>> | From<"GlobalError", Exclude<E, unhandled>>>;
readonly asHttpEffect: () => Effect<HttpServerResponse, unknown, Scope | HttpServerRequest>;
readonly prefixed: (prefix: string) => HttpRouter;
}RouteContext
Service for the matched HTTP route in the current request.
When to use
Use to read captured path parameters and route metadata while handling a request matched by the router.
Details
It provides the route definition and the path parameters captured by the route matcher.
Signature
declare class RouteContext extends Shape<
"effect/http/HttpRouter/RouteContext",
{
readonly params: Readonly<Record<string, string | undefined>>;
readonly route: Route<unknown, unknown>;
},
this
> {
constructor(_: never);
}RouterConfig
Context reference for low-level router configuration.
Details
The value is passed to the route matcher when an HttpRouter is created and defaults to an empty configuration.
Signature
declare const RouterConfig: Reference<Partial<RouterConfig>>;Transforming
prefixPath
Adds a path prefix to a route path.
Details
Trailing slashes are removed from the prefix; / becomes the prefix itself and * becomes a wildcard route under the prefix.
Signature
declare const prefixPath: {
(prefix: string): (self: string) => string;
(self: string, prefix: string): string;
};Utility Types
GlobalProvided type
Services provided to global middleware.
Signature
type GlobalProvided = HttpServerRequest.HttpServerRequest | Scope.Scope;Services provided by the HTTP router, which are available in the request context.
Signature
type Provided =
| HttpServerRequest.HttpServerRequest
| Scope.Scope
| HttpServerRequest.ParsedSearchParams
| RouteContext;Represents a request-level dependency, that needs to be provided by middleware.
Signature
interface Request<Kind extends string, T> {
readonly _: typeof _;
readonly kind: Kind;
readonly type: T;
}
Constructs an empty
HttpRouterservice.Details
The returned router accepts route and middleware registrations and later routes the current
HttpServerRequestto the matchingHttpServerResponse.