HttpLayerRouter
Configuration
RouterConfig
Signature
declare class RouterConfig extends any {
constructor();
}HttpApi
addHttpApi
Signature
declare function addHttpApi<Id extends string, Groups extends Any, E, R>(
api: HttpApi<Id, Groups, E, R>,
options?: {
readonly openapiPath?: `/${string}`;
},
): Layer<
never,
never,
| Generator
| FileSystem
| HttpPlatform
| Path
| HttpRouter
| R
| ToService<Id, Groups>
| ErrorContext<Groups>
>;HttpRouter
Signature
declare function add<E, R>(method: "GET" | "POST" | "PUT" | "DELETE" | "PATCH" | "OPTIONS" | "*", path: PathInput, handler: 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]>>>HttpRouter
Signature
declare const HttpRouter: Tag<HttpRouter, HttpRouter>;HttpRouter interface
Signature
interface HttpRouter {
readonly [TypeId]: typeof TypeId;
readonly add: <E, R>(method: "GET" | "POST" | "PUT" | "DELETE" | "PATCH" | "OPTIONS" | "*", path: PathInput, handler: 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;
}Signature
declare const layer: Layer.Layer<HttpRouter>;Signature
declare const make: Effect<any, unknown, unknown>;toHttpEffect
Signature
declare function toHttpEffect<A, E, R>(
appLayer: Layer<A, E, R>,
): Effect<
Effect<
HttpServerResponse,
RouteNotFound | Only<"Error", R> | Only<"GlobalRequires", R>,
Scope | HttpServerRequest | Only<"GlobalRequires", R> | Only<"Requires", R>
>,
Without<E>,
Scope | Exclude<Without<R>, HttpRouter>
>;Signature
declare const TypeId: unique symbol;Signature
type TypeId = typeof TypeId;A helper function that is the equivalent of:
Signature
declare function use<A, E, R>(
f: (router: HttpRouter) => Effect<A, E, R>,
): Layer<never, E, HttpRouter | Exclude<R, Scope>>;Middleware
A 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> | Predicate<string>;
readonly credentials?: boolean;
readonly exposedHeaders?: readonly Array<string>;
readonly maxAge?: number;
}): Layer<never, never, HttpRouter>disableLogger
A middleware that disables the logger for some routes.
Signature
declare const disableLogger: Layer.Layer<never>;Example
import * as HttpLayerRouter from "@effect/platform/HttpLayerRouter"
import * as HttpServerResponse from "@effect/platform/HttpServerResponse"
import * as Layer from "effect/Layer"
const Route = HttpLayerRouter.add("GET", "/hello", HttpServerResponse.text("Hello, World!")).pipe(
// disable the logger for this route
Layer.provide(HttpLayerRouter.disableLogger),
)middleware
Create a middleware layer that can be used to modify requests and responses.
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>Example
import * as HttpLayerRouter from "@effect/platform/HttpLayerRouter"
import * as HttpMiddleware from "@effect/platform/HttpMiddleware"
import * as HttpServerResponse from "@effect/platform/HttpServerResponse"
import * as Context from "effect/Context"
import * as Effect from "effect/Effect"
import * as Layer from "effect/Layer"
// Here we are defining a CORS middleware
const CorsMiddleware = HttpLayerRouter.middleware(HttpMiddleware.cors()).layer
// You can also use HttpLayerRouter.cors() to create a CORS middleware
class CurrentSession extends Context.Tag("CurrentSession")<
CurrentSession,
{
readonly token: string
}
>() {}
// You can create middleware that provides a service to the HTTP requests.
const SessionMiddleware = HttpLayerRouter.middleware<{
provides: CurrentSession
}>()(
Effect.gen(function* () {
yield* Effect.log("SessionMiddleware initialized")
return (httpEffect) =>
Effect.provideService(httpEffect, CurrentSession, {
token: "dummy-token",
})
}),
).layer
Effect.gen(function* () {
const router = yield* HttpLayerRouter.HttpRouter
yield* router.add(
"GET",
"/hello",
Effect.gen(function* () {
// Requests can now access the current session
const session = yield* CurrentSession
return HttpServerResponse.text(`Hello, World! Your token is ${session.token}`)
}),
)
}).pipe(
Layer.effectDiscard,
// Provide the SessionMiddleware & CorsMiddleware to some routes
Layer.provide([SessionMiddleware, CorsMiddleware]),
)middleware
Middleware interface
Signature
interface Middleware<
Config extends {
error: any;
handles: any;
layerError: any;
layerRequires: any;
provides: any;
requires: any;
},
> {
readonly [MiddlewareTypeId]: 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";
}MiddlewareTypeId
Signature
declare const MiddlewareTypeId: unique symbol;MiddlewareTypeId type
Signature
type MiddlewareTypeId = typeof MiddlewareTypeId;A pseudo-error type that represents an error that should be not handled by the middleware.
Signature
interface unhandled {
readonly _: typeof _;
}Models
RouteContext interface
Signature
interface RouteContext {
readonly [RouteContextTypeId]: typeof RouteContextTypeId;
readonly params: Readonly<Record<string, string | undefined>>;
readonly route: Route<unknown, unknown>;
}PathInput
Signature
type PathInput = `/${string}` | "*";prefixPath
Signature
declare const prefixPath: {
(prefix: string): (self: string) => string;
(self: string, prefix: string): string;
};Re-Exports
FindMyWay
Signature
declare const FindMyWay: any;Request 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;
}Route
prefixRoute
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>;
};Signature
declare function route<E, R>(method: "GET" | "POST" | "PUT" | "DELETE" | "PATCH" | "OPTIONS" | "*", path: PathInput, handler: Effect<HttpServerResponse, E, R> | (request: HttpServerRequest) => Effect<HttpServerResponse, E, R>, options?: {
readonly uninterruptible?: boolean;
}): Route<E, Exclude<R, Provided>>Signature
interface Route<E = never, R = never> {
readonly [RouteTypeId]: typeof RouteTypeId;
readonly handler: Effect<HttpServerResponse, E, R>;
readonly method: HttpMethod | "*";
readonly path: PathInput;
readonly prefix: Option<string>;
readonly uninterruptible: boolean;
}RouteTypeId
Signature
declare const RouteTypeId: unique symbol;RouteTypeId type
Signature
type RouteTypeId = typeof RouteTypeId;Route Context
Signature
declare const params: Effect.Effect<
Readonly<Record<string, string | undefined>>,
never,
RouteContext
>;RouteContext
Signature
declare const RouteContext: Tag<RouteContext, RouteContext>;schemaJson
Signature
declare const schemaJson: <
R,
I extends Partial<{
readonly body: any;
readonly cookies: Readonly<Record<string, string | undefined>>;
readonly headers: Readonly<Record<string, string | undefined>>;
readonly method: Method.HttpMethod;
readonly pathParams: Readonly<Record<string, string | undefined>>;
readonly searchParams: Readonly<Record<string, string | ReadonlyArray<string> | undefined>>;
readonly url: string;
}>,
A,
>(
schema: Schema.Schema<A, I, R>,
options?: ParseOptions,
) => Effect.Effect<
A,
Error.RequestError | ParseResult.ParseError,
RouteContext | R | ServerRequest.HttpServerRequest | ServerRequest.ParsedSearchParams
>;schemaNoBody
Signature
declare const schemaNoBody: <
R,
I extends Partial<{
readonly cookies: Readonly<Record<string, string | undefined>>;
readonly headers: Readonly<Record<string, string | undefined>>;
readonly method: Method.HttpMethod;
readonly pathParams: Readonly<Record<string, string | undefined>>;
readonly searchParams: Readonly<Record<string, string | ReadonlyArray<string> | undefined>>;
readonly url: string;
}>,
A,
>(
schema: Schema.Schema<A, I, R>,
options?: ParseOptions,
) => Effect.Effect<
A,
ParseResult.ParseError,
R | RouteContext | ServerRequest.HttpServerRequest | ServerRequest.ParsedSearchParams
>;schemaParams
Signature
declare const schemaParams: <
A,
I extends Readonly<Record<string, string | ReadonlyArray<string> | undefined>>,
R,
>(
schema: Schema.Schema<A, I, R>,
options?: ParseOptions,
) => Effect.Effect<A, ParseResult.ParseError, R | RouteContext | ServerRequest.ParsedSearchParams>;schemaPathParams
Signature
declare const schemaPathParams: <A, I extends Readonly<Record<string, string | undefined>>, R>(
schema: Schema.Schema<A, I, R>,
options?: ParseOptions,
) => Effect.Effect<A, ParseResult.ParseError, R | RouteContext>;Server
Serves 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,
RouteNotFound | Only<"Error", R> | Only<"GlobalError", R>,
Scope | HttpServerRequest | Only<"Requires", R> | Only<"GlobalRequires", R>
>,
) => Effect<HttpServerResponse, HE, HR>;
readonly routerConfig?: any;
},
): Layer<
A,
Without<E>,
HttpServer | Exclude<Without<R>, HttpRouter> | Exclude<Exclude<HR, GlobalProvided>, HttpRouter>
>;toWebHandler
Signature
declare function toWebHandler<
A,
E,
R extends
| HttpRouter
| Request<"Requires", any>
| Request<"GlobalRequires", any>
| Request<"Error", any>
| Request<"GlobalError", any>,
HE,
HR = Exclude<Only<"Requires", R>, A> | Exclude<Only<"GlobalRequires", R>, A>,
>(
appLayer: Layer<A, E, R>,
options?: {
readonly disableLogger?: boolean;
readonly memoMap?: MemoMap;
readonly middleware?: (
effect: Effect<
HttpServerResponse,
RouteNotFound | Only<"Error", R> | Only<"GlobalError", R>,
Scope | HttpServerRequest | Only<"Requires", R> | Only<"GlobalRequires", R>
>,
) => Effect<HttpServerResponse, HE, HR>;
readonly routerConfig?: any;
},
): {
readonly dispose: () => Promise<void>;
readonly handler: [HR] extends [never]
? (request: Request, context?: Context<never>) => Promise<Response>
: (request: Request, context: Context<HR>) => Promise<Response>;
};
Create a layer that adds a single route to the HTTP router.