The TypeScript code uses AWS CDK to create an AWS API Gateway with a set of predefined REST API resources (like "signup", "login") each supporting specific HTTP methods. It sets up CORS, associates the API with a custom domain using a DNS certificate, and creates a DNS record in Route 53. The API integrates with a Lambda function handler and optionally protects resources with a Cognito User Pools authorizer. It configures a usage plan to throttle the API requests to a specified rate limit.
import {
AuthorizationType,
CognitoUserPoolsAuthorizer,
Cors,
CorsOptions,
EndpointType,
LambdaRestApi,
} from "aws-cdk-lib/aws-apigateway";
import { IFunction } from "aws-cdk-lib/aws-lambda";
import { Certificate, CertificateValidation } from "aws-cdk-lib/aws-certificatemanager";
import { Construct } from "constructs";
import { ARecord, HostedZone, RecordTarget } from "aws-cdk-lib/aws-route53";
import { ApiGateway } from "aws-cdk-lib/aws-route53-targets";
export class ApiGateWay extends Construct {
constructor(
scope: Construct,
id: string,
private handler: IFunction,
private authorizer: CognitoUserPoolsAuthorizer,
) {
super(scope, id);
this.configureResources();
}
private corsOptions: CorsOptions = {
allowOrigins: Cors.ALL_ORIGINS,
allowHeaders: [...Cors.DEFAULT_HEADERS, "access-token", "accept-encoding", "accept"],
allowMethods: Cors.ALL_METHODS,
};
private rootDomainName = "200.land";
private apiDomainName = `api.${this.rootDomainName}`;
public api = new LambdaRestApi(this, "RestApi", {
handler: this.handler,
deployOptions: { stageName: `TwoHunredLandApi-api-prod` },
defaultCorsPreflightOptions: this.corsOptions,
proxy: false,
domainName: {
domainName: this.apiDomainName,
certificate: new Certificate(this, "api-domain-cenrtificate", {
domainName: this.apiDomainName,
validation: CertificateValidation.fromDns(),
}),
endpointType: EndpointType.REGIONAL,
},
});
public apiDNS = new ARecord(this, "apiDNS", {
zone: new HostedZone(this, "api-hosted-zone", { zoneName: this.rootDomainName }),
recordName: "api",
target: RecordTarget.fromAlias(new ApiGateway(this.api)),
});
private resources = [
{ name: "signup", methods: ["POST"], isProtected: false },
{ name: "login", methods: ["POST"], isProtected: false },
{ name: "verify", methods: ["POST"], isProtected: false },
{ name: "chat", methods: ["POST"], isProtected: false },
{ name: "forgot-password", methods: ["POST"], isProtected: false },
{ name: "reset-password", methods: ["POST"], isProtected: false },
];
private configureResources(): void {
this.resources.forEach(({ name, methods, isProtected }) => {
const reasource = this.api.root.addResource(name, {
defaultCorsPreflightOptions: this.corsOptions,
});
methods.forEach(method => {
reasource.addMethod(method, undefined, {
...(isProtected && {
authorizationType: AuthorizationType.COGNITO,
authorizer: this.authorizer,
}),
});
});
});
this.api.addUsagePlan("api-usage-plan", { throttle: { rateLimit: 10 } });
}
}