Skip to content

Commit f3219c3

Browse files
authored
feat(apigatewayv2): http api (#6432)
Co-authored by: Niranjan Jayakar <[email protected]> closes #5301
1 parent 40fa93a commit f3219c3

25 files changed

+1526
-10
lines changed
Lines changed: 96 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,110 @@
11
## AWS::APIGatewayv2 Construct Library
2+
23
<!--BEGIN STABILITY BANNER-->
34
---
45

56
![cfn-resources: Stable](https://img.shields.io/badge/cfn--resources-stable-success.svg?style=for-the-badge)
67

78
> All classes with the `Cfn` prefix in this module ([CFN Resources](https://docs.aws.amazon.com/cdk/latest/guide/constructs.html#constructs_lib)) are always stable and safe to use.
89
10+
![cdk-constructs: Experimental](https://img.shields.io/badge/cdk--constructs-experimental-important.svg?style=for-the-badge)
11+
12+
> The APIs of higher level constructs in this module are experimental and under active development. They are subject to non-backward compatible changes or removal in any future version. These are not subject to the [Semantic Versioning](https://semver.org/) model and breaking changes will be announced in the release notes. This means that while you may use them, you may need to update your source code when upgrading to a newer version of this package.
13+
914
---
1015
<!--END STABILITY BANNER-->
1116

12-
This module is part of the [AWS Cloud Development Kit](https://github.com/aws/aws-cdk) project.
17+
## Table of Contents
18+
19+
- [Introduction](#introduction)
20+
- [HTTP API](#http-api)
21+
- [Defining HTTP APIs](#defining-http-apis)
22+
- [Publishing HTTP APIs](#publishing-http-apis)
23+
24+
## Introduction
25+
26+
Amazon API Gateway is an AWS service for creating, publishing, maintaining, monitoring, and securing REST, HTTP, and WebSocket
27+
APIs at any scale. API developers can create APIs that access AWS or other web services, as well as data stored in the AWS Cloud.
28+
As an API Gateway API developer, you can create APIs for use in your own client applications. Read the
29+
[Amazon API Gateway Developer Guide](https://docs.aws.amazon.com/apigateway/latest/developerguide/welcome.html).
30+
31+
This module supports features under [API Gateway v2](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/AWS_ApiGatewayV2.html)
32+
that lets users set up Websocket and HTTP APIs.
33+
REST APIs can be created using the `@aws-cdk/aws-apigateway` module.
34+
35+
## HTTP API
36+
37+
HTTP APIs enable creation of RESTful APIs that integrate with AWS Lambda functions, known as Lambda proxy integration,
38+
or to any routable HTTP endpoint, known as HTTP proxy integration.
39+
40+
### Defining HTTP APIs
41+
42+
HTTP APIs have two fundamental concepts - Routes and Integrations.
43+
44+
Routes direct incoming API requests to backend resources. Routes consist of two parts: an HTTP method and a resource
45+
path, such as, `GET /books`. Learn more at [Working with
46+
routes](https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-develop-routes.html). Use the `ANY` method
47+
to match any methods for a route that are not explicitly defined.
48+
49+
Integrations define how the HTTP API responds when a client reaches a specific Route. HTTP APIs support two types of
50+
integrations - Lambda proxy integration and HTTP proxy integration. Learn more at [Configuring
51+
integrations](https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-develop-integrations.html).
52+
53+
The code snippet below configures a route `GET /books` with an HTTP proxy integration and uses the `ANY` method to
54+
proxy all other HTTP method calls to `/books` to a lambda proxy.
1355

1456
```ts
15-
import * as apigatewayv2 from '@aws-cdk/aws-apigatewayv2';
57+
const getBooksIntegration = new HttpProxyIntegration({
58+
url: 'https://get-books-proxy.myproxy.internal',
59+
});
60+
61+
const booksDefaultFn = new lambda.Function(stack, 'BooksDefaultFn', { ... });
62+
const booksDefaultIntegration = new LambdaProxyIntegration({
63+
handler: booksDefaultFn,
64+
});
65+
66+
const httpApi = new HttpApi(stack, 'HttpApi');
67+
68+
httpApi.addRoutes({
69+
path: '/books',
70+
methods: [ HttpMethod.GET ],
71+
integration: getBooksIntegration,
72+
});
73+
httpApi.addRoutes({
74+
path: '/books',
75+
methods: [ HttpMethod.ANY ],
76+
integration: booksDefaultIntegration,
77+
});
78+
```
79+
80+
The `defaultIntegration` option while defining HTTP APIs lets you create a default catch-all integration that is
81+
matched when a client reaches a route that is not explicitly defined.
82+
83+
```ts
84+
new HttpApi(stack, 'HttpProxyApi', {
85+
defaultIntegration: new HttpProxyIntegration({
86+
url:'http://example.com',
87+
}),
88+
});
89+
```
90+
91+
### Publishing HTTP APIs
92+
93+
A Stage is a logical reference to a lifecycle state of your API (for example, `dev`, `prod`, `beta`, or `v2`). API
94+
stages are identified by their stage name. Each stage is a named reference to a deployment of the API made available for
95+
client applications to call.
96+
97+
Use `HttpStage` to create a Stage resource for HTTP APIs. The following code sets up a Stage, whose URL is available at
98+
`https://{api_id}.execute-api.{region}.amazonaws.com/beta`.
99+
100+
```ts
101+
new HttpStage(stack, 'Stage', {
102+
httpApi: api,
103+
stageName: 'beta',
104+
});
16105
```
106+
107+
If you omit the `stageName` will create a `$default` stage. A `$default` stage is one that is served from the base of
108+
the API's URL - `https://{api_id}.execute-api.{region}.amazonaws.com/`.
109+
110+
Note that, `HttpApi` will always creates a `$default` stage, unless the `createDefaultStage` property is unset.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export * from './integration';
2+
export * from './route';
3+
export * from './stage';
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { IResource } from '@aws-cdk/core';
2+
3+
/**
4+
* Represents an integration to an API Route.
5+
*/
6+
export interface IIntegration extends IResource {
7+
/**
8+
* Id of the integration.
9+
* @attribute
10+
*/
11+
readonly integrationId: string;
12+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { IResource } from '@aws-cdk/core';
2+
3+
/**
4+
* Represents a route.
5+
*/
6+
export interface IRoute extends IResource {
7+
/**
8+
* Id of the Route
9+
* @attribute
10+
*/
11+
readonly routeId: string;
12+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { IResource } from '@aws-cdk/core';
2+
3+
/**
4+
* Represents a Stage.
5+
*/
6+
export interface IStage extends IResource {
7+
/**
8+
* The name of the stage; its primary identifier.
9+
* @attribute
10+
*/
11+
readonly stageName: string;
12+
}
13+
14+
/**
15+
* Options required to create a new stage.
16+
* Options that are common between HTTP and Websocket APIs.
17+
*/
18+
export interface CommonStageOptions {
19+
/**
20+
* The name of the stage. See `StageName` class for more details.
21+
* @default '$default' the default stage of the API. This stage will have the URL at the root of the API endpoint.
22+
*/
23+
readonly stageName?: string;
24+
25+
/**
26+
* Whether updates to an API automatically trigger a new deployment.
27+
* @default false
28+
*/
29+
readonly autoDeploy?: boolean;
30+
}
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
import { Construct, IResource, Resource } from '@aws-cdk/core';
2+
import { CfnApi, CfnApiProps } from '../apigatewayv2.generated';
3+
import { IHttpRouteIntegration } from './integration';
4+
import { BatchHttpRouteOptions, HttpMethod, HttpRoute, HttpRouteKey } from './route';
5+
import { HttpStage, HttpStageOptions } from './stage';
6+
7+
/**
8+
* Represents an HTTP API
9+
*/
10+
export interface IHttpApi extends IResource {
11+
/**
12+
* The identifier of this API Gateway HTTP API.
13+
* @attribute
14+
*/
15+
readonly httpApiId: string;
16+
}
17+
18+
/**
19+
* Properties to initialize an instance of `HttpApi`.
20+
*/
21+
export interface HttpApiProps {
22+
/**
23+
* Name for the HTTP API resoruce
24+
* @default - id of the HttpApi construct.
25+
*/
26+
readonly apiName?: string;
27+
28+
/**
29+
* An integration that will be configured on the catch-all route ($default).
30+
* @default - none
31+
*/
32+
readonly defaultIntegration?: IHttpRouteIntegration;
33+
34+
/**
35+
* Whether a default stage and deployment should be automatically created.
36+
* @default true
37+
*/
38+
readonly createDefaultStage?: boolean;
39+
}
40+
41+
/**
42+
* Options for the Route with Integration resoruce
43+
*/
44+
export interface AddRoutesOptions extends BatchHttpRouteOptions {
45+
/**
46+
* The path at which all of these routes are configured.
47+
*/
48+
readonly path: string;
49+
50+
/**
51+
* The HTTP methods to be configured
52+
* @default HttpMethod.ANY
53+
*/
54+
readonly methods?: HttpMethod[];
55+
}
56+
57+
/**
58+
* Create a new API Gateway HTTP API endpoint.
59+
* @resource AWS::ApiGatewayV2::Api
60+
*/
61+
export class HttpApi extends Resource implements IHttpApi {
62+
/**
63+
* Import an existing HTTP API into this CDK app.
64+
*/
65+
public static fromApiId(scope: Construct, id: string, httpApiId: string): IHttpApi {
66+
class Import extends Resource implements IHttpApi {
67+
public readonly httpApiId = httpApiId;
68+
}
69+
return new Import(scope, id);
70+
}
71+
72+
public readonly httpApiId: string;
73+
private readonly defaultStage: HttpStage | undefined;
74+
75+
constructor(scope: Construct, id: string, props?: HttpApiProps) {
76+
super(scope, id);
77+
78+
const apiName = props?.apiName ?? id;
79+
80+
const apiProps: CfnApiProps = {
81+
name: apiName,
82+
protocolType: 'HTTP',
83+
};
84+
const resource = new CfnApi(this, 'Resource', apiProps);
85+
this.httpApiId = resource.ref;
86+
87+
if (props?.defaultIntegration) {
88+
new HttpRoute(this, 'DefaultRoute', {
89+
httpApi: this,
90+
routeKey: HttpRouteKey.DEFAULT,
91+
integration: props.defaultIntegration,
92+
});
93+
}
94+
95+
if (props?.createDefaultStage === undefined || props.createDefaultStage === true) {
96+
this.defaultStage = new HttpStage(this, 'DefaultStage', {
97+
httpApi: this,
98+
autoDeploy: true,
99+
});
100+
}
101+
}
102+
103+
/**
104+
* Get the URL to the default stage of this API.
105+
* Returns `undefined` if `createDefaultStage` is unset.
106+
*/
107+
public get url(): string | undefined {
108+
return this.defaultStage ? this.defaultStage.url : undefined;
109+
}
110+
111+
/**
112+
* Add a new stage.
113+
*/
114+
public addStage(id: string, options: HttpStageOptions): HttpStage {
115+
return new HttpStage(this, id, {
116+
httpApi: this,
117+
...options,
118+
});
119+
}
120+
121+
/**
122+
* Add multiple routes that uses the same configuration. The routes all go to the same path, but for different
123+
* methods.
124+
*/
125+
public addRoutes(options: AddRoutesOptions): HttpRoute[] {
126+
const methods = options.methods ?? [ HttpMethod.ANY ];
127+
return methods.map((method) => new HttpRoute(this, `${method}${options.path}`, {
128+
httpApi: this,
129+
routeKey: HttpRouteKey.with(options.path, method),
130+
integration: options.integration,
131+
}));
132+
}
133+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export * from './api';
2+
export * from './route';
3+
export * from './integration';
4+
export * from './integrations';
5+
export * from './stage';

0 commit comments

Comments
 (0)