Skip to content
Effect 4.0 is here. One ecosystem. Zero dependencies.

HttpApiBuilder

19 exports Since v1.0.0 Source

Constructors

Since v1.0.0

Create a top-level HttpApi layer.

Signature

declare function api<Id extends string, Groups extends Any, E, R>(api: HttpApi<Id, Groups, E, R>): Layer<Api, never, R | ToService<Id, Groups> | ErrorContext<Groups>>

Signature

declare const buildMiddleware: <Id extends string, Groups extends HttpApiGroup.HttpApiGroup.Any, E, R>(api: HttpApi.HttpApi<Id, Groups, E, R>) => Effect.Effect<(effect: Effect.Effect<HttpServerResponse.HttpServerResponse, unknown>) => Effect.Effect<HttpServerResponse.HttpServerResponse, unknown, never>>
Since v1.0.0

Construct an HttpApp from an HttpApi instance.

Signature

declare const httpApp: Effect.Effect<HttpApp.Default<never, HttpRouter.HttpRouter.DefaultServices>, never, Router | HttpApi.Api | Middleware>
Since v1.0.0

Build an HttpApp from an HttpApi instance, and serve it using an HttpServer.

Optionally, you can provide a middleware function that will be applied to the HttpApp before serving.

Signature

declare function serve<R = never>(middleware?: (httpApp: Default) => Default<never, R>): Layer<never, never, Api | DefaultServices | HttpServer | Exclude<R, Scope | HttpServerRequest>>

Construct an http web handler from an HttpApi instance.

Signature

declare function toWebHandler<LA, LE>(layer: Layer<Api | DefaultServices | LA, LE>, options?: {
readonly memoMap?: MemoMap;
readonly middleware?: (httpApp: Default) => Default<never, Api | Router | DefaultServices>;
}): {
readonly dispose: () => Promise<void>;
readonly handler: (request: Request, context?: Context<never>) => Promise<Response>;
}

Example

import { HttpApi, HttpApiBuilder, HttpServer } from "@effect/platform"
import { Layer } from "effect"
class MyApi extends HttpApi.make("api") {}
const MyApiLive = HttpApiBuilder.api(MyApi)
const { dispose, handler } = HttpApiBuilder.toWebHandler(
Layer.mergeAll(
MyApiLive,
// you could also use NodeHttpServer.layerContext, depending on your
// server's platform
HttpServer.layerContext
)
)

Global

Since v1.0.0

Signature

type MiddlewareFn<Error, R = HttpRouter.HttpRouter.Provided> = (httpApp: HttpApp.Default) => HttpApp.Default<Error, R>

Handlers

Since v1.0.0

Create a Layer that will implement all the endpoints in an HttpApi.

An unimplemented Handlers instance is passed to the build function, which you can use to add handlers to the group.

You can implement endpoints using the handlers.handle api.

Signature

declare function group<ApiId extends string, Groups extends Any, ApiError, ApiR, Name extends string, Return>(api: HttpApi<ApiId, Groups, ApiError, ApiR>, groupName: Name, build: (handlers: FromGroup<ApiError, ApiR, Extract<Groups, {
readonly identifier: Name;
}>>) => ValidateReturn<Return>): Layer<ApiGroup<ApiId, Name>, Error<Return>, Exclude<Context<Return>, Scope> | Exclude<Middleware<Extract<Groups, {
readonly identifier: Name;
}>>, Scope>>
Since v1.0.0

Create a Handler for a single endpoint.

Signature

declare function handler<ApiId extends string, Groups extends Any, ApiError, ApiR, GroupName extends string, Name extends string, R>(_api: HttpApi<ApiId, Groups, ApiError, ApiR>, _groupName: GroupName, _name: Name, f: HandlerWithName<Endpoints<Extract<Groups, {
readonly identifier: GroupName;
}>>, Name, ApiError | Error<Extract<Groups, {
readonly identifier: GroupName;
}>>, R>): HandlerWithName<Endpoints<Extract<Groups, {
readonly identifier: GroupName;
}>>, Name, ApiError | Error<Extract<Groups, {
readonly identifier: GroupName;
}>>, R>
Since v1.0.0

Handlers

interface
Since v1.0.0

Represents a handled HttpApi.

Signature

interface Handlers<E, Provides, R, Endpoints extends HttpApiEndpoint.HttpApiEndpoint.Any = never> extends Pipeable {
readonly [HandlersTypeId]: {
_Endpoints: Covariant<Endpoints>;
};
readonly group: AnyWithProps;
readonly handlers: Chunk<Item<E, R>>;
handle<Name extends string, R1>(name: Name, handler: HandlerWithName<Endpoints, Name, E, R1>, options?: {
readonly uninterruptible?: boolean;
}): Handlers<E, Provides, R | Exclude<Exclude<R1, DefaultServices | Provided | Provides<Extract<Context<Extract<Endpoints, {
readonly name: Name;
}>>, AnyId>>>, Provides> | Exclude<Exclude<Context<Extract<Endpoints, {
readonly name: Name;
}>>, DefaultServices | Provided | Provides<Extract<Context<Extract<Endpoints, {
readonly name: Name;
}>>, AnyId>>>, Provides>, Exclude<Endpoints, {
readonly name: Name;
}>>;
handleRaw<Name extends string, R1>(name: Name, handler: HandlerRawWithName<Endpoints, Name, E, R1>, options?: {
readonly uninterruptible?: boolean;
}): Handlers<E, Provides, R | Exclude<Exclude<R1, DefaultServices | Provided | Provides<Extract<Context<Extract<Endpoints, {
readonly name: Name;
}>>, AnyId>>>, Provides> | Exclude<Exclude<Context<Extract<Endpoints, {
readonly name: Name;
}>>, DefaultServices | Provided | Provides<Extract<Context<Extract<Endpoints, {
readonly name: Name;
}>>, AnyId>>>, Provides>, Exclude<Endpoints, {
readonly name: Name;
}>>;
}

Signature

declare const HandlersTypeId: unique symbol
Since v1.0.0

Signature

type HandlersTypeId = typeof HandlersTypeId

Middleware

Create an HttpApi level middleware Layer.

Signature

declare const middleware: {
<EX = never, RX = never>(middleware: MiddlewareFn<never, Provided> | Effect<MiddlewareFn<never, Provided>, EX, RX>, options?: {
readonly withContext?: false;
}): Layer<never, EX, Exclude<RX, Scope>>;
<R, EX = never, RX = never>(middleware: MiddlewareFn<never, R> | Effect<MiddlewareFn<never, R>, EX, RX>, options: {
readonly withContext: true;
}): Layer<never, EX, Exclude<RX, Scope> | Exclude<Exclude<R, Provided>, Scope>>;
<ApiId extends string, Groups extends Any, Error, ErrorR, EX = never, RX = never>(api: HttpApi<ApiId, Groups, Error, ErrorR>, middleware: MiddlewareFn<NoInfer<Error>, Provided> | Effect<MiddlewareFn<NoInfer<Error>, Provided>, EX, RX>, options?: {
readonly withContext?: false;
}): Layer<never, EX, Exclude<RX, Scope>>;
<ApiId extends string, Groups extends Any, Error, ErrorR, R, EX = never, RX = never>(api: HttpApi<ApiId, Groups, Error, ErrorR>, middleware: MiddlewareFn<NoInfer<Error>, R> | Effect<MiddlewareFn<NoInfer<Error>, R>, EX, RX>, options: {
readonly withContext: true;
}): Layer<never, EX, Exclude<RX, Scope> | Exclude<Exclude<R, Provided>, Scope>>;
}

Signature

declare class Middleware extends any {
constructor();
static readonly layer: Layer<unknown, never, never>;
}

A CORS middleware layer that can be provided to the HttpApiBuilder.serve layer.

Signature

declare function middlewareCors(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>

A middleware that adds an openapi.json endpoint to the API.

Signature

declare function middlewareOpenApi(options?: {
readonly additionalPropertiesStrategy?: AdditionalPropertiesStrategy;
readonly path?: `/${string}`;
}): Layer<never, never, Api>

Set a cookie from an HttpApiSecurity.HttpApiKey instance.

You can use this api before returning a response from an endpoint handler.

Signature

declare function securitySetCookie(self: ApiKey, value: string | Redacted<string>, options?: {
readonly domain?: string;
readonly expires?: Date;
readonly httpOnly?: boolean;
readonly maxAge?: any;
readonly partitioned?: boolean;
readonly path?: string;
readonly priority?: "low" | "medium" | "high";
readonly sameSite?: "lax" | "strict" | "none";
readonly secure?: boolean;
}): Effect<void>

Example

handlers.handle(
"authenticate",
(_) => HttpApiBuilder.securitySetCookie(security, "secret123")
)

Router

Since v1.0.0

The router that the API endpoints are attached to.

Signature

declare class Router extends any {
constructor(_: never);
}

Security

Signature

declare function securityDecode<Security extends HttpApiSecurity>(self: Security): Effect<Type<Security>, never, HttpServerRequest | ParsedSearchParams>