Skip to content

ApiGatewayV2

Reference doc for the `sst.aws.ApiGatewayV2` component.

The ApiGatewayV2 component lets you add an Amazon API Gateway HTTP API to your app.

Create the API

sst.config.ts
const api = new sst.aws.ApiGatewayV2("MyApi");

Add a custom domain

sst.config.ts
new sst.aws.ApiGatewayV2("MyApi", {
domain: "api.example.com"
});

Add routes

sst.config.ts
api.route("GET /", "src/get.handler");
api.route("POST /", "src/post.handler");

Configure the routes

You can configure the route.

sst.config.ts
api.route("GET /", "src/get.handler", {
auth: { iam: true }
});

Configure the route handler

You can configure the route handler function.

sst.config.ts
api.route("POST /", {
handler: "src/post.handler",
memory: "2048 MB"
});

Default props for all routes

You can use the transform to set some default props for all your routes. For example, instead of setting the memory for each route.

sst.config.ts
api.route("GET /", { handler: "src/get.handler", memory: "2048 MB" });
api.route("POST /", { handler: "src/post.handler", memory: "2048 MB" });

You can set it through the transform.

sst.config.ts
const api = new sst.aws.ApiGatewayV2("MyApi", {
transform: {
route: {
handler: (args, opts) => {
// Set the default if it's not set by the route
args.memory ??= "2048 MB";
}
}
}
});
api.route("GET /", "src/get.handler");
api.route("POST /", "src/post.handler");

With this we set the memory if it’s not overridden by the route.


Constructor

new ApiGatewayV2(name, args?, opts?)

Parameters

ApiGatewayV2Args

accessLog?

Type Input<Object>

Default {retention: “1 month”}

Configure the API Gateway logs in CloudWatch. By default, access logs are enabled and kept for 1 month.

{
accessLog: {
retention: "forever"
}
}

accessLog.retention?

Type Input<1 day | 3 days | 5 days | 1 week | 2 weeks | 1 month | 2 months | 3 months | 4 months | 5 months | 6 months | 1 year | 13 months | 18 months | 2 years | 3 years | 5 years | 6 years | 7 years | 8 years | 9 years | 10 years | forever>

Default 1 month

The duration the API Gateway logs are kept in CloudWatch.

cors?

Type Input<boolean | Object>

Default true

Customize the CORS (Cross-origin resource sharing) settings for your HTTP API.

Disable CORS.

{
cors: false
}

Only enable the GET and POST methods for https://example.com.

{
cors: {
allowMethods: ["GET", "POST"],
allowOrigins: ["https://example.com"]
}
}

cors.allowCredentials?

Type Input<boolean>

Default false

Allow cookies or other credentials in requests to the HTTP API.

{
cors: {
allowCredentials: true
}
}

cors.allowHeaders?

Type Input<Input<string>[]>

Default [”*”]

The HTTP headers that origins can include in requests to the HTTP API.

{
cors: {
allowHeaders: ["date", "keep-alive", "x-custom-header"]
}
}

cors.allowMethods?

Type Input<Input<GET | POST | PUT | DELETE | HEAD | OPTIONS | PATCH | *>[]>

Default [”*”]

The HTTP methods that are allowed when calling the HTTP API.

{
cors: {
allowMethods: ["GET", "POST", "DELETE"]
}
}

Or the wildcard for all methods.

{
cors: {
allowMethods: ["*"]
}
}

cors.allowOrigins?

Type Input<Input<string>[]>

Default [”*”]

The origins that can access the HTTP API.

{
cors: {
allowOrigins: ["https://www.example.com", "http://localhost:60905"]
}
}

Or the wildcard for all origins.

{
cors: {
allowOrigins: ["*"]
}
}

cors.exposeHeaders?

Type Input<Input<string>[]>

Default []

The HTTP headers you want to expose in your function to an origin that calls the HTTP API.

{
cors: {
exposeHeaders: ["date", "keep-alive", "x-custom-header"]
}
}

cors.maxAge?

Type Input<${number} minute | ${number} minutes | ${number} hour | ${number} hours | ${number} second | ${number} seconds | ${number} day | ${number} days>

Default “0 seconds”

The maximum amount of time the browser can cache results of a preflight request. By default the browser doesn’t cache the results. The maximum value is 86400 seconds or 1 day.

{
cors: {
maxAge: "1 day"
}
}

domain?

Type Input<string | Object>

Set a custom domain for your HTTP API.

Automatically manages domains hosted on AWS Route 53, Cloudflare, and Vercel. For other providers, you’ll need to pass in a cert that validates domain ownership and add the DNS records.

By default this assumes the domain is hosted on Route 53.

{
domain: "example.com"
}

For domains hosted on Cloudflare.

{
domain: {
name: "example.com",
dns: sst.cloudflare.dns()
}
}

domain.cert?

Type Input<string>

The ARN of an ACM (AWS Certificate Manager) certificate that proves ownership of the domain. By default, a certificate is created and validated automatically.

To manually set up a domain on an unsupported provider, you’ll need to:

  1. Validate that you own the domain by creating an ACM certificate. You can either validate it by setting a DNS record or by verifying an email sent to the domain owner.
  2. Once validated, set the certificate ARN as the cert and set dns to false.
  3. Add the DNS records in your provider to point to the API Gateway URL.
{
domain: {
name: "example.com",
dns: false,
cert: "arn:aws:acm:us-east-1:112233445566:certificate/3a958790-8878-4cdc-a396-06d95064cf63"
}
}

domain.dns?

Type Input<false | sst.aws.dns | sst.cloudflare.dns | sst.vercel.dns>

Default sst.aws.dns

The DNS provider to use for the domain. Defaults to the AWS.

Takes an adapter that can create the DNS records on the provider. This can automate validating the domain and setting up the DNS routing.

Supports Route 53, Cloudflare, and Vercel adapters. For other providers, you’ll need to set dns to false and pass in a certificate validating ownership via cert.

Specify the hosted zone ID for the Route 53 domain.

{
domain: {
name: "example.com",
dns: sst.aws.dns({
zone: "Z2FDTNDATAQYW2"
})
}
}

Use a domain hosted on Cloudflare, needs the Cloudflare provider.

{
domain: {
name: "example.com",
dns: sst.cloudflare.dns()
}
}

Use a domain hosted on Vercel, needs the Vercel provider.

{
domain: {
name: "example.com",
dns: sst.vercel.dns()
}
}

domain.name?

Type Input<string>

The custom domain you want to use.

{
domain: {
name: "example.com"
}
}

Can also include subdomains based on the current stage.

{
domain: {
name: `${$app.stage}.example.com`
}
}

domain.nameId?

Type Input<string>

Use an existing API Gateway domain name.

By default, a new API Gateway domain name is created. If you’d like to use an existing domain name, set the nameId to the ID of the domain name and do not pass in name.

{
domain: {
nameId: "example.com"
}
}

domain.path?

Type Input<string>

The base mapping for the custom domain. This adds a suffix to the URL of the API.

Given the following base path and domain name.

{
domain: {
name: "api.example.com",
path: "v1"
}
}

The full URL of the API will be https://api.example.com/v1/.

By default there is no base path, so if the name is api.example.com, the full URL will be https://api.example.com.

Type Input<any[]>

Link resources to all your API Gateway routes.

Linked resources will be merged with the resources linked to each route.

Takes a list of resources to link to all the routes.

{
link: [bucket, stripeKey]
}

transform?

Type Object

Transform how this component creates its underlying resources.

transform.api?

Type ApiArgs | (args: ApiArgs, opts: ComponentResourceOptions, name: string) => void

Transform the API Gateway HTTP API resource.

transform.domainName?

Type DomainNameArgs | (args: DomainNameArgs, opts: ComponentResourceOptions, name: string) => void

Transform the API Gateway HTTP API domain name resource.

transform.logGroup?

Type LogGroupArgs | (args: LogGroupArgs, opts: ComponentResourceOptions, name: string) => void

Transform the CloudWatch LogGroup resource used for access logs.

transform.route?

Type Object

Transform the routes. This is called for every route that is added.

You can use this to set any default props for all the routes and their handler function. Like the other transforms, you can either pass in an object or a callback.

Here we are setting a default memory of 2048 MB for our routes.

{
transform: {
route: {
handler: (args, opts) => {
// Set the default if it's not set by the route
args.memory ??= "2048 MB";
}
}
}
}

Defaulting to IAM auth for all our routes.

{
transform: {
route: {
args: (props) => {
// Set the default if it's not set by the route
props.auth ??= { iam: true };
}
}
}
}
transform.route.args?

Type ApiGatewayV2RouteArgs | (args: ApiGatewayV2RouteArgs, opts: ComponentResourceOptions, name: string) => void

Transform the arguments for the route.

transform.route.handler?

Type FunctionArgs | (args: FunctionArgs, opts: ComponentResourceOptions, name: string) => void

Transform the handler function of the route.

transform.stage?

Type StageArgs | (args: StageArgs, opts: ComponentResourceOptions, name: string) => void

Transform the API Gateway HTTP API stage resource.

Type VpcLinkArgs | (args: VpcLinkArgs, opts: ComponentResourceOptions, name: string) => void

Transform the API Gateway HTTP API VPC link resource.

vpc?

Type Input<Vpc | Object>

Configure the API to connect to private resources in a virtual private cloud or VPC. This creates a VPC link for your HTTP API.

Create a Vpc component.

sst.config.ts
const myVpc = new sst.aws.Vpc("MyVpc");

And pass it in. The VPC link will be placed in the public subnets.

{
vpc: myVpc
}

The above is equivalent to:

{
vpc: {
securityGroups: myVpc.securityGroups,
subnets: myVpc.publicSubnets
}
}

vpc.securityGroups

Type Input<Input<string>[]>

A list of VPC security group IDs.

vpc.subnets

Type Input<Input<string>[]>

A list of VPC subnet IDs.

Properties

nodes

Type Object

The underlying resources this component creates.

nodes.api

Type Api

The Amazon API Gateway HTTP API.

nodes.logGroup

Type LogGroup

The CloudWatch LogGroup for the access logs.

Type undefined | VpcLink

The API Gateway HTTP API VPC link.

nodes.domainName

Type Output<DomainName>

The API Gateway HTTP API domain name.

url

Type Output<string>

The URL of the API.

If the domain is set, this is the URL with the custom domain. Otherwise, it’s the autogenerated API Gateway URL.

SDK

Use the SDK in your runtime to interact with your infrastructure.


This is accessible through the Resource object in the SDK.

  • url string

    The URL of the API.

    If the domain is set, this is the URL with the custom domain. Otherwise, it’s the autogenerated API Gateway URL.

Methods

addAuthorizer

addAuthorizer(args)

Parameters

Returns ApiGatewayV2Authorizer

Add an authorizer to the API Gateway HTTP API.

Add a Lambda authorizer.

sst.config.ts
api.addAuthorizer({
name: "myAuthorizer",
lambda: {
function: "src/authorizer.index"
}
});

Add a JWT authorizer.

sst.config.ts
const authorizer = api.addAuthorizer({
name: "myAuthorizer",
jwt: {
issuer: "https://issuer.com/",
audiences: ["https://api.example.com"],
identitySource: "$request.header.AccessToken"
}
});

Add a Cognito UserPool as a JWT authorizer.

sst.config.ts
const pool = new sst.aws.CognitoUserPool("MyUserPool");
const poolClient = userPool.addClient("Web");
const authorizer = api.addAuthorizer({
name: "myCognitoAuthorizer",
jwt: {
issuer: $interpolate`https://cognito-idp.${aws.getRegionOutput().name}.amazonaws.com/${pool.id}`,
audiences: [poolClient.id]
}
});

Now you can use the authorizer in your routes.

sst.config.ts
api.route("GET /", "src/get.handler", {
auth: {
jwt: {
authorizer: authorizer.id
}
}
});

route

route(rawRoute, handler, args?)

Parameters

  • rawRoute string

    The path for the route.
  • handler Input<string | FunctionArgs | “arn:aws:lambda:${string}”>

    The function that’ll be invoked.
  • args? ApiGatewayV2RouteArgs

    Configure the route.

Returns ApiGatewayV2LambdaRoute

Add a route to the API Gateway HTTP API. The route is a combination of

  • An HTTP method and a path, {METHOD} /{path}.
  • Or a $default route.

A method could be one of GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS, or ANY. Here ANY matches any HTTP method.

The path can be a combination of

  • Literal segments, /notes, /notes/new, etc.
  • Parameter segments, /notes/{noteId}, /notes/{noteId}/attachments/{attachmentId}, etc.
  • Greedy segments, /{proxy+}, /notes/{proxy+}, etc. The {proxy+} segment is a greedy segment that matches all child paths. It needs to be at the end of the path.

The $default is a reserved keyword for the default route. It’ll be matched if no other route matches.

When a request comes in, the API Gateway will look for the most specific match. If no route matches, the $default route will be invoked.

Add a simple route.

sst.config.ts
api.route("GET /", "src/get.handler");

Match any HTTP method.

sst.config.ts
api.route("ANY /", "src/route.handler");

Add a default route.

sst.config.ts
api.route("GET /", "src/get.handler")
api.route($default, "src/default.handler");

Add a parameterized route.

sst.config.ts
api.route("GET /notes/{id}", "src/get.handler");

Add a greedy route.

sst.config.ts
api.route("GET /notes/{proxy+}", "src/greedy.handler");

Enable auth for a route.

sst.config.ts
api.route("GET /", "src/get.handler")
api.route("POST /", "src/post.handler", {
auth: {
iam: true
}
});

Customize the route handler.

sst.config.ts
api.route("GET /", {
handler: "src/get.handler",
memory: "2048 MB"
});

Or pass in the ARN of an existing Lambda function.

sst.config.ts
api.route("GET /", "arn:aws:lambda:us-east-1:123456789012:function:my-function");

routePrivate

routePrivate(rawRoute, arn, args?)

Parameters

  • rawRoute string

    The path for the route.
  • arn Input<string>

    The ARN of the AWS Load Balander or Cloud Map service.
  • args? ApiGatewayV2RouteArgs

    Configure the route.

Returns ApiGatewayV2PrivateRoute

Adds a private route to the API Gateway HTTP API.

To add private routes, you need to have a VPC link. Make sure to pass in a vpc. Learn more about adding private routes.

Add a route to Application Load Balander.

sst.config.ts
const loadBalancerArn = "arn:aws:elasticloadbalancing:us-east-1:123456789012:loadbalancer/app/my-load-balancer/50dc6c495c0c9188";
api.routePrivate("GET /", loadBalancerArn);

Add a route to AWS Cloud Map service.

sst.config.ts
const serviceArn = "arn:aws:servicediscovery:us-east-2:123456789012:service/srv-id?stage=prod&deployment=green_deployment";
api.routePrivate("GET /", serviceArn);

Enable IAM authentication for a route.

sst.config.ts
api.routePrivate("GET /", serviceArn, {
auth: {
iam: true
}
});

routeUrl

routeUrl(rawRoute, url, args?)

Parameters

  • rawRoute string

    The path for the route.
  • url string

    The URL to forward to.
  • args? ApiGatewayV2RouteArgs

    Configure the route.

Returns ApiGatewayV2UrlRoute

Add a URL route to the API Gateway HTTP API.

Add a simple route.

sst.config.ts
api.routeUrl("GET /", "https://google.com");

Enable auth for a route.

sst.config.ts
api.routeUrl("POST /", "https://google.com", {
auth: {
iam: true
}
});

ApiGatewayV2AuthorizerArgs

jwt?

Type Input<Object>

Create a JWT or JSON Web Token authorizer that can be used by the routes.

Configure JWT auth.

{
jwt: {
issuer: "https://issuer.com/",
audiences: ["https://api.example.com"],
identitySource: "$request.header.AccessToken"
}
}

You can also use Cognito as the identity provider.

{
jwt: {
audiences: [userPoolClient.id],
issuer: $interpolate`https://cognito-idp.${aws.getArnOutput(userPool).region}.amazonaws.com/${userPool.id}`,
}
}

Where userPool and userPoolClient are:

const userPool = new aws.cognito.UserPool();
const userPoolClient = new aws.cognito.UserPoolClient();

jwt.audiences

Type Input<Input<string>[]>

List of the intended recipients of the JWT. A valid JWT must provide an aud that matches at least one entry in this list.

jwt.identitySource?

Type Input<string>

Default “$request.header.Authorization”

Specifies where to extract the JWT from the request.

jwt.issuer

Type Input<string>

Base domain of the identity provider that issues JSON Web Tokens.

{
issuer: "https://issuer.com/"
}

lambda?

Type Input<Object>

Create a Lambda authorizer that can be used by the routes.

Configure Lambda auth.

{
lambda: {
function: "src/authorizer.index"
}
}

lambda.function

Type Input<string | FunctionArgs>

The Lambda authorizer function. Takes the handler path or the function args.

Add a simple authorizer.

{
function: "src/authorizer.index"
}

Customize the authorizer handler.

{
function: {
handler: "src/authorizer.index",
memory: "2048 MB"
}
}

lambda.identitySources?

Type Input<Input<string>[]>

Default [“$request.header.Authorization”]

Specifies where to extract the identity from.

{
identitySources: ["$request.header.RequestToken"]
}

lambda.payload?

Type Input<1.0 | 2.0>

Default “2.0”

The JWT payload version.

{
payload: "2.0"
}

lambda.response?

Type Input<simple | iam>

Default “simple”

The response type.

{
response: "iam"
}

lambda.ttl?

Type Input<${number} minute | ${number} minutes | ${number} hour | ${number} hours | ${number} second | ${number} seconds>

Default Not cached

The time to live (TTL) for the authorizer.

{
ttl: "300 seconds"
}

name

Type string

The name of the authorizer.

{
name: "myAuthorizer"
}

transform?

Type Object

Transform how this component creates its underlying resources.

transform.authorizer?

Type AuthorizerArgs | (args: AuthorizerArgs, opts: ComponentResourceOptions, name: string) => void

Transform the API Gateway authorizer resource.

ApiGatewayV2RouteArgs

auth?

Type Input<false | Object>

Default false

Enable auth for your HTTP API. By default, auth is disabled.

{
auth: {
iam: true
}
}

auth.iam?

Type Input<boolean>

Enable IAM authorization for a given API route. When IAM auth is enabled, clients need to use Signature Version 4 to sign their requests with their AWS credentials.

auth.jwt?

Type Input<Object>

Enable JWT or JSON Web Token authorization for a given API route. When JWT auth is enabled, clients need to include a valid JWT in their requests.

You can configure JWT auth.

{
auth: {
jwt: {
authorizer: myAuthorizer.id,
scopes: ["read:profile", "write:profile"]
}
}
}

Where myAuthorizer is created by calling the addAuthorizer method.

auth.jwt.authorizer

Type Input<string>

Authorizer ID of the JWT authorizer.

auth.jwt.scopes?

Type Input<Input<string>[]>

Defines the permissions or access levels that the JWT grants. If the JWT does not have the required scope, the request is rejected. By default it does not require any scopes.

auth.lambda?

Type Input<string>

Enable custom Lambda authorization for a given API route. Pass in the authorizer ID.

{
auth: {
lambda: myAuthorizer.id
}
}

Where myAuthorizer is created by calling the addAuthorizer method.

transform?

Type Object

Transform how this component creates its underlying resources.

transform.integration?

Type IntegrationArgs | (args: IntegrationArgs, opts: ComponentResourceOptions, name: string) => void

Transform the API Gateway HTTP API integration resource.

transform.route?

Type RouteArgs | (args: RouteArgs, opts: ComponentResourceOptions, name: string) => void

Transform the API Gateway HTTP API route resource.