Skip to content

AWS.ApiGatewayV2 reference

Source: src/AWS/ApiGatewayV2/Api.ts

An Amazon API Gateway v2 API — the root of an HTTP API or WebSocket API.

HTTP APIs are the modern, cheaper, faster front door for Lambda functions (compared to REST v1). WebSocket APIs provide two-way real-time messaging backed by Lambda route handlers. Child resources (Integration, Route, Stage, Authorizer) reference the API by passing api in their props.

For the common “HTTP API in front of a Lambda function” case, prefer the high-level HttpApi helper which wires up the integration, route, stage, and invoke permission in one call.

Minimal HTTP API

import * as ApiGatewayV2 from "alchemy/AWS/ApiGatewayV2";
const api = yield* ApiGatewayV2.Api("Api", {});

HTTP API with CORS

const api = yield* ApiGatewayV2.Api("Api", {
corsConfiguration: {
AllowOrigins: ["https://example.com"],
AllowMethods: ["GET", "POST"],
AllowHeaders: ["content-type"],
MaxAge: 3600,
},
});
const api = yield* ApiGatewayV2.Api("WsApi", {
protocolType: "WEBSOCKET",
routeSelectionExpression: "$request.body.action",
});
const api = yield* ApiGatewayV2.Api("Api", {
disableExecuteApiEndpoint: true,
});

Source: src/AWS/ApiGatewayV2/ApiMapping.ts

An API Gateway v2 API mapping — serves an API stage under a custom DomainName, optionally at a base path.

ApiMappingResource: Mapping APIs onto a domain

Section titled “ApiMappingResource: Mapping APIs onto a domain”

Map an API at the domain root

yield* ApiGatewayV2.ApiMapping("Root", {
api,
domainName: domain.domainName,
stage: stage.stageName,
});

Map a second API under /v2

yield* ApiGatewayV2.ApiMapping("V2", {
api: apiV2,
domainName: domain.domainName,
stage: "$default",
apiMappingKey: "v2",
});

Source: src/AWS/ApiGatewayV2/Authorizer.ts

An API Gateway v2 Authorizer — controls access to HTTP/WebSocket API routes via JWT validation or a Lambda (REQUEST) authorizer.

The common HTTP API authorizer: API Gateway validates the caller’s JWT against the issuer’s JWKS and matches the audience — no Lambda invoked.

const authorizer = yield* ApiGatewayV2.Authorizer("Jwt", {
api,
authorizerType: "JWT",
identitySource: ["$request.header.Authorization"],
jwtConfiguration: {
Issuer: `https://cognito-idp.us-west-2.amazonaws.com/${userPoolId}`,
Audience: [clientId],
},
});
yield* ApiGatewayV2.Route("Secure", {
api,
routeKey: "GET /me",
integration,
authorizationType: "JWT",
authorizerId: authorizer.authorizerId,
});

AuthorizerResource: Lambda (REQUEST) authorizers

Section titled “AuthorizerResource: Lambda (REQUEST) authorizers”
const authorizer = yield* ApiGatewayV2.Authorizer("Lambda", {
api,
authorizerType: "REQUEST",
identitySource: ["$request.header.Authorization"],
authorizerUri: invocationUri,
authorizerPayloadFormatVersion: "2.0",
enableSimpleResponses: true,
});

Source: src/AWS/ApiGatewayV2/DomainName.ts

An API Gateway v2 custom domain name.

Requires a validated ACM certificate in the same region. Point DNS (a Route 53 alias or CNAME) at the returned ApiGatewayDomainName target and map APIs onto the domain with ApiMapping.

const domain = yield* ApiGatewayV2.DomainName("Domain", {
domainName: "api.example.com",
domainNameConfigurations: [{
CertificateArn: certificate.certificateArn,
EndpointType: "REGIONAL",
SecurityPolicy: "TLS_1_2",
}],
});
yield* ApiGatewayV2.ApiMapping("Mapping", {
api,
domainName: domain.domainName,
stage: stage.stageName,
});

Source: src/AWS/ApiGatewayV2/ExportApi.ts

Runtime binding for exporting an HTTP API’s OpenAPI 3.0 definition (apigateway:GET on /apis/{apiId}/exports/{specification}).

Bind an Api inside a function runtime to serve or snapshot the live API definition — e.g. publishing your own /openapi.json route or diffing deployed routes against the source of truth. The response body is a byte Stream of the JSON (or YAML) document. Provide ApiGatewayV2.ExportApiHttp on the Function effect to implement the binding.

// init
const exportApi = yield* ApiGatewayV2.ExportApi(api);
// runtime
const exported = yield* exportApi({ OutputType: "JSON" });
const document = yield* Stream.mkString(Stream.decodeText(exported.body!));

Source: src/AWS/ApiGatewayV2/Integration.ts

An API Gateway v2 Integration — the backend target a Route forwards to.

For HTTP APIs the common integration is AWS_PROXY with payload format 2.0, pointing directly at a Lambda function ARN. For WebSocket APIs the integrationUri must be the full Lambda invocation URI.

IntegrationResource: Lambda proxy integration (HTTP API)

Section titled “IntegrationResource: Lambda proxy integration (HTTP API)”
const integration = yield* ApiGatewayV2.Integration("Fn", {
api,
integrationType: "AWS_PROXY",
integrationUri: fn.functionArn,
payloadFormatVersion: "2.0",
});

IntegrationResource: HTTP proxy integration

Section titled “IntegrationResource: HTTP proxy integration”
const integration = yield* ApiGatewayV2.Integration("Upstream", {
api,
integrationType: "HTTP_PROXY",
integrationUri: "https://example.com/{proxy}",
integrationMethod: "ANY",
payloadFormatVersion: "1.0",
});

Source: src/AWS/ApiGatewayV2/ManageConnections.ts

Runtime binding for the WebSocket @connections management API (execute-api:ManageConnections).

Bind this to a WebSocket API Stage inside a function runtime to push messages to connected clients — the flagship server-push primitive for WebSocket APIs. The binding grants execute-api:ManageConnections scoped to the stage’s @connections ARN and targets the stage’s callback endpoint (https://{apiId}.execute-api.{region}.amazonaws.com/{stage}).

Provide ApiGatewayV2.ManageConnectionsHttp on the hosting function’s Effect (Effect.provide(ApiGatewayV2.ManageConnectionsHttp)) to satisfy the binding.

const connections = yield* ApiGatewayV2.ManageConnections(stage);
yield* ApiGatewayV2.onWebSocketRoute(api, { routeKey: "$default" }, (event) =>
connections
.postToConnection({
ConnectionId: event.requestContext.connectionId,
Data: `echo:${event.body ?? ""}`,
})
.pipe(
Effect.asVoid,
// The peer may have disconnected between send and receive.
Effect.catchTag("GoneException", () => Effect.void),
Effect.orDie,
),
);
yield* connections.deleteConnection({ ConnectionId: staleConnectionId });

Source: src/AWS/ApiGatewayV2/ResetAuthorizersCache.ts

Runtime binding for resetting a stage’s authorizer result cache (apigateway:DELETE on /apis/{apiId}/stages/{stageName}/cache/authorizers).

Bind a Stage inside a function runtime to drop cached Lambda authorizer verdicts — e.g. immediately revoking access after a permission change, without waiting out authorizerResultTtl. Provide ApiGatewayV2.ResetAuthorizersCacheHttp on the Function effect to implement the binding.

// init
const resetAuthorizersCache = yield* ApiGatewayV2.ResetAuthorizersCache(stage);
// runtime
yield* resetAuthorizersCache();

Source: src/AWS/ApiGatewayV2/Route.ts

An API Gateway v2 Route — matches incoming requests (or WebSocket messages) and forwards them to an Integration.

Catch-all $default route

yield* ApiGatewayV2.Route("Default", {
api,
routeKey: "$default",
integration,
});

Method + path route

yield* ApiGatewayV2.Route("ListItems", {
api,
routeKey: "GET /items",
integration,
});
yield* ApiGatewayV2.Route("Connect", {
api,
routeKey: "$connect",
integration,
});
yield* ApiGatewayV2.Route("Secure", {
api,
routeKey: "GET /me",
integration,
authorizationType: "JWT",
authorizerId: authorizer.authorizerId,
});

Source: src/AWS/ApiGatewayV2/Stage.ts

An API Gateway v2 Stage — the deployed, callable endpoint of an HTTP or WebSocket API.

StageResource: The $default auto-deploy stage

Section titled “StageResource: The $default auto-deploy stage”

The canonical modern setup is a single $default stage with autoDeploy: true — every route/integration change goes live automatically at the API root endpoint, with no Deployment juggling.

const stage = yield* ApiGatewayV2.Stage("Stage", {
api,
autoDeploy: true,
});
// stage.invokeUrl === api.apiEndpoint
const dev = yield* ApiGatewayV2.Stage("Dev", {
api,
stageName: "dev",
autoDeploy: true,
stageVariables: { logLevel: "debug" },
});
const stage = yield* ApiGatewayV2.Stage("Stage", {
api,
autoDeploy: true,
defaultRouteSettings: {
ThrottlingBurstLimit: 100,
ThrottlingRateLimit: 50,
},
});

Source: src/AWS/ApiGatewayV2/VpcLink.ts

An API Gateway v2 VPC link — lets an HTTP API reach private resources (ALB/NLB listeners, Cloud Map services) inside a VPC.

Unlike the v1 VPC link (NLB-only, ~10 min provisioning), the v2 link is subnet/security-group based and provisions in ~1–2 minutes.

const link = yield* ApiGatewayV2.VpcLink("Link", {
subnetIds: [subnetA.subnetId, subnetB.subnetId],
securityGroupIds: [securityGroup.securityGroupId],
});
yield* ApiGatewayV2.Integration("Private", {
api,
integrationType: "HTTP_PROXY",
integrationUri: listener.listenerArn,
integrationMethod: "ANY",
connectionType: "VPC_LINK",
connectionId: link.vpcLinkId,
payloadFormatVersion: "1.0",
});

Source: src/AWS/ApiGatewayV2/WebSocketEventSource.ts

Event source connecting a WebSocket Api route to the hosting Lambda function.

At deploy time the Lambda implementation (Lambda.WebSocketEventSource) materializes the Integration, Route, and invoke Permission for the route; at runtime it dispatches matching WebSocket proxy events to the handler. Subscribe routes with onWebSocketRoute and provide Lambda.WebSocketEventSource on the hosting function.

WebSocketEventSource: Handling WebSocket Routes

Section titled “WebSocketEventSource: Handling WebSocket Routes”
export default MyFunction.make(
{ main: import.meta.url },
Effect.gen(function* () {
const api = yield* ApiGatewayV2.Api("WsApi", {
protocolType: "WEBSOCKET",
routeSelectionExpression: "$request.body.action",
});
const stage = yield* ApiGatewayV2.Stage("WsStage", {
api,
stageName: "prod",
autoDeploy: true,
});
const connections = yield* ApiGatewayV2.ManageConnections(stage);
yield* ApiGatewayV2.onWebSocketRoute(api, { routeKey: "$connect" }, () =>
Effect.succeed({ statusCode: 200 }),
);
yield* ApiGatewayV2.onWebSocketRoute(api, { routeKey: "$default" }, (event) =>
connections
.postToConnection({
ConnectionId: event.requestContext.connectionId,
Data: `echo:${event.body ?? ""}`,
})
.pipe(
Effect.asVoid,
Effect.catchTag("GoneException", () => Effect.void),
Effect.orDie,
),
);
return {};
}).pipe(
Effect.provide(
Layer.mergeAll(
Lambda.WebSocketEventSource,
ApiGatewayV2.ManageConnectionsHttp,
),
),
),
);