ApiGatewayV1Api
caution
This is the SST v0.x Constructs doc. SST v1 is now released. If you are using v1, see the v1 Constructs doc. If you are looking to upgrade to v1, check out the migration steps.
The ApiGatewayV1Api
construct is a higher level CDK construct that makes it easy to create an API Gateway REST API. It provides a simple way to define the routes in your API. And allows you to configure the specific Lambda functions if necessary. It also allows you to configure authorization and custom domains. See the examples for more details.
note
If you are creating a new API, use the Api
construct instead.
The Api construct uses API Gateway V2. It's both faster and cheaper. However, if you need features like Usage Plans and API keys, use the ApiGatewayV1Api
construct instead. You can check out a detailed comparison here.
Initializer
new ApiGatewayV1Api(scope: Construct, id: string, props: ApiGatewayV1ApiProps)
Parameters
- scope
Construct
- id
string
- props
ApiGatewayV1ApiProps
Examples
The ApiGatewayV1Api
construct is designed to make it easy to get started with, while allowing for a way to fully configure it as well. Let's look at how, through a couple of examples.
Using the minimal config
import { ApiGatewayV1Api } from "@serverless-stack/resources";
new ApiGatewayV1Api(this, "Api", {
routes: {
"GET /notes": "src/list.main",
"POST /notes": "src/create.main",
"GET /notes/{id}": "src/get.main",
"PUT /notes/{id}": "src/update.main",
"DELETE /notes/{id}": "src/delete.main",
},
});
Note that, the route key can have extra spaces in between, they are just ignored.
Adding routes
Add routes after the API has been created.
const api = new ApiGatewayV1Api(this, "Api", {
routes: {
"GET /notes": "src/list.main",
"POST /notes": "src/create.main",
},
});
api.addRoutes(this, {
"GET /notes/{id}": "src/get.main",
"PUT /notes/{id}": "src/update.main",
"DELETE /notes/{id}": "src/delete.main",
});
Lazily adding routes
Create an empty Api construct and lazily add the routes.
const api = new ApiGatewayV1Api(this, "Api");
api.addRoutes(this, {
"GET /notes": "src/list.main",
"POST /notes": "src/create.main",
});
Adding catch-all route
Add routes after the API has been created.
const api = new ApiGatewayV1Api(this, "Api", {
routes: {
"GET /notes": "src/list.main",
"ANY /{proxy+}": "src/catch.main",
},
});
Specifying function props for all the routes
You can extend the minimal config, to set some function props and have them apply to all the routes.
new ApiGatewayV1Api(this, "Api", {
defaultFunctionProps: {
timeout: 20,
environment: { tableName: table.tableName },
},
routes: {
"GET /notes": "src/list.main",
"POST /notes": "src/create.main",
},
});
Using the full config
If you wanted to configure each Lambda function separately, you can pass in the ApiGatewayV1ApiRouteProps
.
new ApiGatewayV1Api(this, "Api", {
routes: {
"GET /notes": {
function: {
srcPath: "src/",
handler: "list.main",
environment: { tableName: "NOTES_TABLE" },
},
},
},
});
Note that, you can set the defaultFunctionProps
while using the function
per route. The function
will just override the defaultFunctionProps
. Except for the environment
, the layers
, and the permissions
properties, which will be merged.
new ApiGatewayV1Api(this, "Api", {
defaultFunctionProps: {
timeout: 20,
environment: { tableName: "NOTES_TABLE" },
},
routes: {
"GET /notes": {
function: {
handler: "list.main",
timeout: 10,
environment: { bucketName: "NOTES_BUCKET" },
},
},
"POST /notes": "create.main",
},
});
So in the above example, the GET /notes
function doesn't use the timeout
that is set in the defaultFunctionProps
. It'll instead use the one that is defined in the function definition (10 seconds
). And the function will have both the tableName
and the bucketName
environment variables set.
Configuring Regional endpoint
Configure the internally created CDK RestApi
instance.
import { EndpointType } from "aws-cdk-lib/aws-apigateway";
new ApiGatewayV1Api(this, "Api", {
restApi: {
endpointConfiguration: {
types: [EndpointType.REGIONAL],
},
},
routes: {
"GET /notes": "src/list.main",
},
});
Importing an existing Rest Api
Override the internally created CDK RestApi
instance.
import { RestApi } from "aws-cdk-lib/aws-apigateway";
new ApiGatewayV1Api(this, "Api", {
restApi: RestApi.fromRestApiAttributes(this, "MyRestApi", {
restApiId,
rootResourceId,
}),
importedPaths: {
"/notes": "slx2bn",
"/users": "uu8xs3",
},
routes: {
"GET /notes/{noteId}": "src/getNote.main",
"GET /users/{userId}": "src/getUser.main",
},
});
Configuring access log
Configuring the access log format
Use a CSV format instead of default JSON format.
new ApiGatewayV1Api(this, "Api", {
accessLog:
"$context.identity.sourceIp,$context.requestTime,$context.httpMethod,$context.routeKey,$context.protocol,$context.status,$context.responseLength,$context.requestId",
routes: {
"GET /notes": "src/list.main",
},
});
Configuring the log retention setting
new ApiGatewayV1Api(this, "Api", {
accessLog: {
retention: "ONE_WEEK",
}
routes: {
"GET /notes": "src/list.main",
},
});
Configuring CORS
Override the default behavior of allowing all methods, and only allow the GET method.
new ApiGatewayV1Api(this, "Api", {
restApi: {
defaultCorsPreflightOptions: {
allowOrigins: ['"*"'],
},
},
routes: {
"GET /notes": "src/list.main",
},
});
Configuring custom domains
You can also configure the API with a custom domain. SST currently supports domains that are configured using Route 53. If your domains are hosted elsewhere, you can follow this guide to migrate them to Route 53.
Using the basic config
new ApiGatewayV1Api(this, "Api", {
customDomain: "api.domain.com",
routes: {
"GET /notes": "src/list.main",
},
});
Using the full config
import { EndpointType } from "aws-cdk-lib/aws-apigateway";
new ApiGatewayV1Api(this, "Api", {
customDomain: {
domainName: "api.domain.com",
hostedZone: "domain.com",
endpointType: EndpointType.EDGE,
path: "v1",
},
routes: {
"GET /notes": "src/list.main",
},
});
Mapping multiple APIs to the same domain
const usersApi = new ApiGatewayV1Api(this, "UsersApi", {
customDomain: {
domainName: "api.domain.com",
path: "users",
},
});
new ApiGatewayV1Api(this, "PostsApi", {
customDomain: {
domainName: usersApi.apiGatewayDomain,
path: "posts",
},
});
Importing an existing API Gateway custom domain
import { DomainName } from "aws-cdk-lib/aws-apigateway";
new ApiGatewayV1Api(this, "Api", {
customDomain: {
domainName: DomainName.fromDomainNameAttributes(this, "MyDomain", {
domainName,
domainNameAliasHostedZoneId,
domainNameAliasTarget,
}),
path: "newPath",
},
routes: {
"GET /notes": "src/list.main",
},
});
Importing an existing certificate
import { Certificate } from "aws-cdk-lib/aws-certificatemanager";
new ApiGatewayV1Api(this, "Api", {
customDomain: {
domainName: "api.domain.com",
certificate: Certificate.fromCertificateArn(this, "MyCert", certArn),
},
routes: {
"GET /notes": "src/list.main",
},
});
Loading domain name from SSM parameter
If you have the domain name stored in AWS SSM Parameter Store, you can reference the value as the domain name:
import { StringParameter } from "aws-cdk-lib/aws-ssm";
const rootDomain = StringParameter.valueForStringParameter(this, `/myApp/domain`);
new ApiGatewayV1Api(this, "Api", {
customDomain: {
domainName: `api.${rootDomain}`,
hostedZone: rootDomain,
},
routes: {
"GET /notes": "src/list.main",
},
});
Note that, normally SST will look for a hosted zone by stripping out the first part of the domainName
. But this is not possible when the domainName
is a reference. Since its value will be resolved at deploy time. So you'll need to specify the hostedZone
explicitly.
Attaching permissions
You can attach a set of permissions to all or some of the routes.
For the entire API
Allow the entire API to access S3.
const api = new ApiGatewayV1Api(this, "Api", {
routes: {
"GET /notes": "src/list.main",
"POST /notes": "src/create.main",
"GET /notes/{id}": "src/get.main",
"PUT /notes/{id}": "src/update.main",
"DELETE /notes/{id}": "src/delete.main",
},
});
api.attachPermissions(["s3"]);
For a specific route
Allow one of the routes to access S3.
const api = new ApiGatewayV1Api(this, "Api", {
routes: {
"GET /notes": "src/list.main",
"POST /notes": "src/create.main",
"GET /notes/{id}": "src/get.main",
"PUT /notes/{id}": "src/update.main",
"DELETE /notes/{id}": "src/delete.main",
},
});
api.attachPermissionsToRoute("GET /notes", ["s3"]);
Adding auth
You can use IAM or JWT to add auth to your APIs.
Adding IAM authorization
You can secure your APIs (and other AWS resources) by setting the defaultAuthorizationType
to IAM
and using the sst.Auth
construct.
import { AuthorizationType } from "aws-cdk-lib/aws-apigateway";
new ApiGatewayV1Api(this, "Api", {
defaultAuthorizationType: AuthorizationType.IAM,
routes: {
"GET /notes": "list.main",
"POST /notes": "create.main",
},
});
Adding IAM authorization to a specific route
You can also secure specific routes in your APIs by setting the authorizationType
to AWS_IAM
and using the sst.Auth
construct.
import { AuthorizationType } from "aws-cdk-lib/aws-apigateway";
new ApiGatewayV1Api(this, "Api", {
routes: {
"GET /public": "src/public.main",
"GET /private": {
function: "src/private.main",
methodOptions: {
authorizationType: AuthorizationType.IAM,
},
},
},
});
Adding CUSTOM authorization
CUSTOM allows using a Lambda function to authorize users to access your API. Note that, this is a different authorization method when compared to using AWS_IAM
and the sst.Auth
construct, which allows you to secure other AWS resources as well.
import * as apigateway from "aws-cdk-lib/aws-apigateway";
const authorizer = new apigateway.RequestAuthorizer(this, "Authorizer", {
handler: new Function(this, "AuthorizerFunction", {
handler: "src/authorizer.main",
}),
identitySources: [apigateway.IdentitySource.header("Authorization")],
});
new ApiGatewayV1Api(this, "Api", {
defaultAuthorizationType: apigateway.AuthorizationType.CUSTOM,
defaultAuthorizer: authorizer,
routes: {
"GET /notes": "src/list.main",
},
});
Adding CUSTOM authorization to a specific route
You can also secure specific routes using CUSTOM by setting the authorizationType
per route.
import * as apigateway from "aws-cdk-lib/aws-apigateway";
const authorizer = new apigateway.RequestAuthorizer(this, "Authorizer", {
handler: new Function(this, "AuthorizerFunction", {
handler: "src/authorizer.main",
}),
identitySources: [apigateway.IdentitySource.header("Authorization")],
});
new ApiGatewayV1Api(this, "Api", {
routes: {
"GET /public": "src/public.main",
"GET /private": {
function: {
handler: "src/private.main",
methodOptions: {
authorizationType: apigateway.AuthorizationType.CUSTOM,
defaultAuthorizer: authorizer,
},
},
},
},
});
Using Cognito User Pool as the authorizer
You can also use Cognito User Pools as an authorizer.
import * as apigateway from "aws-cdk-lib/aws-apigateway";
const authorizer = new apigateway.CognitoUserPoolsAuthorizer(
this,
"Authorizer",
{
cognitoUserPools: [userPool],
}
);
new ApiGatewayV1Api(this, "Api", {
defaultAuthorizationType: apigateway.AuthorizationType.COGNITO,
defaultAuthorizer: authorizer,
defaultAuthorizationScopes: ["user.id", "user.email"],
routes: {
"GET /notes": "src/list.main",
},
});
Getting the function for a route
const api = new ApiGatewayV1Api(this, "Api", {
routes: {
"GET /notes": "src/list.main",
"POST /notes": "src/create.main",
"GET /notes/{id}": "src/get.main",
"PUT /notes/{id}": "src/update.main",
"DELETE /notes/{id}": "src/delete.main",
},
});
const listFunction = api.getFunction("GET /notes");
Properties
An instance of ApiGatewayV1Api
contains the following properties.
url
Type: string
The URL of the Api.
routes
Type: string[]
The routes for the Api.
restApi
Type: cdk.aws-apigateway.RestApi
The internally created CDK RestApi
instance.
accessLogGroup?
Type: cdk.aws-logs.LogGroup
If access logs are enabled, this is the internally created CDK LogGroup
instance.
customDomainUrl?
Type: string
If custom domain is enabled, this is the custom domain URL of the Api.
apiGatewayDomain?
Type: cdk.aws-apigateway.DomainName
If custom domain is enabled, this is the internally created CDK DomainName
instance.
acmCertificate?
Type: cdk.aws-certificatemanager.Certificate
If custom domain is enabled, this is the internally created CDK Certificate
instance.
Methods
An instance of ApiGatewayV1Api
contains the following methods.
getFunction
getFunction(routeKey: string): Function
Parameters
- routeKey
string
Returns
Get the instance of the internally created Function
, for a given route key. Where the routeKey
is the key used to define a route. For example, GET /notes
.
addRoutes
addRoutes(scope: cdk.Construct, routes: { [key: string]: FunctionDefinition | ApiGatewayV1ApiRouteProps })
Parameters
- scope
cdk.Construct
- routes
{ [key: string]: FunctionDefinition | ApiGatewayV1ApiRouteProps }
An associative array with the key being the route as a string and the value is either a FunctionDefinition
or the ApiGatewayV1ApiRouteProps
.
attachPermissions
attachPermissions(permissions: Permissions)
Parameters
- permissions
Permissions
Attaches the given list of permissions to all the routes. This allows the functions to access other AWS resources.
Internally calls Function.attachPermissions
.
attachPermissionsToRoute
attachPermissionsToRoute(routeKey: string, permissions: Permissions)
Parameters
routeKey
string
permissions
Permissions
Attaches the given list of permissions to a specific route. This allows that function to access other AWS resources.
Internally calls Function.attachPermissions
.
ApiGatewayV1ApiProps
routes?
Type : { [key: string]: FunctionDefinition | apigatewayv1apirouteprops }
, defaults to {}
The routes for this API. Takes an associative array, with the key being the route as a string and the value is either a FunctionDefinition
.
{
"GET /notes": "src/list.main",
"GET /notes/{id}": "src/get.main",
}
Or the ApiGatewayV1ApiRouteProps.
import * as apigateway from "aws-cdk-lib/aws-apigateway";
{
"GET /notes": {
function: {
handler: "src/list.main",
environment: {
TABLE_NAME: "notesTable",
},
},
methodOptions: {
authorizationType: apigateway.AuthorizationType.IAM,
},
},
}
cors?
Type : boolean
, defaults to true
CORS support for all the endpoints in the API. Takes a boolean
value. To fully customizize the CORS configuration, pass in a restApi
with the defaultCorsPreflightOptions
property.
By setting cors
to true
, SST also adds the CORS header to 4xx and 5xx gateway response.
accessLog?
Type : boolean | string | ApiGatewayV1ApiAcccessLogProps
, defaults to true
CloudWatch access logs for the API. Takes a boolean
value, a string
with log format, or a ApiGatewayV1ApiAcccessLogProps
.
customDomain?
Type : string | ApiGatewayV1ApiCustomDomainProps
The customDomain for this API. SST currently supports domains that are configured using Route 53. If your domains are hosted elsewhere, you can follow this guide to migrate them to Route 53.
Takes either the domain as a string.
"api.domain.com"
Or the ApiCustomDomainProps.
{
domainName: "api.domain.com",
hostedZone: "domain.com",
path: "v1",
}
Note that, SST automatically creates a Route 53 A record in the hosted zone to point the custom domain to the API Gateway domain.
restApi?
Type : cdk.aws-apigateway.RestApiProps | cdk.aws-apigateway.IRestApi
Pass in a cdk.aws-apigateway.RestApiProps
value to override the default settings this construct uses to create the CDK RestApi
internally.
Or, pass in an instance of the CDK cdk.aws-apigateway.IRestApi
. SST will use the provided CDK RestApi
instead of creating one internally.
importedPaths?
Type : { [path: string]: string }
If you are importing an existing API Gateway REST API project, you can import existing route paths by providing a list of paths with their corresponding resource ids.
{
"/notes": "slx2bn",
"/users": "uu8xs3",
}
API Gateway REST API is structured in a tree structure:
- Each path part is a separate API Gateway resource object.
- And a path part is a child resource of the preceding part.
So the part path /notes, is a child resource of the root resource /. And /notes/{noteId} is a child resource of /notes. If /notes has been created in the imported API, you have to import it before creating the /notes/{noteId} child route.
defaultFunctionProps?
Type : FunctionProps
, defaults to {}
The default function props to be applied to all the Lambda functions in the API. If the function
is specified for a route, these default values are overridden. Except for the environment
, the layers
, and the permissions
properties, which will be merged.
defaultAuthorizationType?
Type : `cdk.aws-apigateway.AuthorizationType
The authorization type for all the endpoints in the API. Supports IAM, COGNITO, CUSTOM and NONE. Defaults to no authorization, NONE
.
The IAM method together with the sst.Api
construct uses the Cognito Identity Pool. This allows you to secure other AWS resources as well.
On the other hand, the COGNITO and CUSTOM methods are for securing APIs specifically.
If you are just starting out, we recommend using the IAM method.
defaultAuthorizer?
Type : `cdk.aws-apigateway.IAuthorizer
The authorizer for all the routes in the API.
defaultAuthorizationScopes?
Type : string[]
, defaults to []
An array of scopes to include in the authorization when using JWT
as the defaultAuthorizationType
. These will be merged with the scopes from the attached authorizer.
For example, ["user.id", "user.email"]
.
ApiGatewayV1ApiRouteProps
function
Type : FunctionDefinition
The function definition used to create the function for this route.
methodOptions?
Type : cdk.aws-apigateway.MethodOptions
The options to be applied to the HTTP method for a route.
integrationOptions?
Type : cdk.aws-apigateway.LambdaIntegrationOptions
The options to be applied to the Lambda integration for a route.
ApiGatewayV1ApiAccessLogProps
Takes the following props in addition to the cdk.aws-apigateway.CfnStage.AccessLogSettingProperty
.
retention?
Type : string
, defaults to TWO_YEARS
The following values are accepted: "ONE_DAY", "THREE_DAYS", "FIVE_DAYS", "ONE_WEEK", "TWO_WEEKS", "ONE_MONTH", "TWO_MONTHS", "THREE_MONTHS", "FOUR_MONTHS", "FIVE_MONTHS", "SIX_MONTHS", "ONE_YEAR", "THIRTEEN_MONTHS", "EIGHTEEN_MONTHS", "TWO_YEARS", "FIVE_YEARS", "TEN_YEARS", and "INFINITE".
ApiGatewayV1ApiCustomDomainProps
domainName
Type : string | cdk.aws-apigateway.IDomainName
The domain to be assigned to the API endpoint. Takes the custom domain as a string
(ie. api.domain.com
) or a cdk.aws-apigateway.IDomainName
.
Currently supports domains that are configured using Route 53.
hostedZone?
Type : string | cdk.aws-route53.HostedZone
, defaults to the base domain
The hosted zone in Route 53 that contains the domain. Takes the name of the hosted zone as a string
or the hosted zone construct cdk.aws-route53.HostedZone
. By default, SST will look for a hosted zone by stripping out the first part of the domainName
that's passed in. So, if your domainName
is api.domain.com
. SST will default the hostedZone
to domain.com
.
Set this option if SST cannot find the hosted zone in Route 53.
certificate?
Type : cdk.aws-certificatemanager.Certificate
, defaults to undefined
The certificate for the domain. By default, SST will create a certificate with the domain name from the domainName
option.
Set this option if you have an existing certificate in AWS Certificate Manager you want to use.
path?
Type : string
, defaults to undefined
The base mapping for the custom domain. For example, by setting the domainName
to api.domain.com
and path
to v1
, the custom domain URL for the API will become https://api.domain.com/v1
. If the path
is not set, the custom domain URL will be https://api.domain.com
.
caution
You cannot change the path once it has been set.
Note, if the path
was not defined initially, it cannot be defined later. If the path
was initially defined, it cannot be later changed to undefined. Instead, you'd need to remove the customDomain
option from the construct, deploy it. And then set it to the new path value.
endpointType?
Type : cdk.aws-apigateway.EndpointType
, defaults to REGIONAL
The type of endpoint for this DomainName.
mtls?
Type : cdk.aws-apigateway.MTLSConfig
, defaults to mTLS not configured
The mutual TLS authentication configuration for a custom domain name.
securityPolicy?
Type : cdk.aws-apigateway.SecurityPolicy
, defaults to TLS_1_0
The Transport Layer Security (TLS) version + cipher suite for this domain name.