Skip to content

Commit b0f3857

Browse files
author
Elad Ben-Israel
authored
feat(aws-apigateway): API Gateway Construct Library (#665)
Introduce an initial construct library for API Gateway. By all means it does not cover the entire surface area of API Gateway, but provides basic support for defining API gateway configurations (resources/methods hierarchy). Integration support includes `LambdaIntegration` which accepts a `lambda.Function`, sets up the appropriate permissions and binds it to an API method. Includes many "smart defaults" at every level such as: - Automatically define a `Deployment` and a `Stage` for the API, which will be recreated every time the API configuration changes (by generating the logical ID of the AWS::ApiGateway::Deployment resource from a hash of the API configuration, similarly to SAM). - Automatically configure a role for API Gateway to allow writing CloudWatch logs and alarms. - Specify `defaultIntegration` at the API level which will apply to all methods without integration. Supports defining APIs like this: ```ts const integ = new apigw.LambdaIntegration(toysLambdaHandler); const api = new apigw.RestApi(this, 'my-awesome-api'); api.root.onMethod('GET', new apigw.HttpIntegration('https://amazon.com/toys')); const toys = api.root.addResource('toys', { defaultIntegration: integ }); toys.addMethod('ANY'); const toy = toys.addResource('{toy}'); toy.addMethod('GET'); // get a toy toy.addMethod('DELETE'); // remove a toy ``` See [README] for more details. [README]: https://github.com/awslabs/aws-cdk/blob/c99e7285e7b24700cfd4d52f6da32cffe12c511c/packages/%40aws-cdk/aws-apigateway/README.md ### Framework Changes * __resolve__: allow object keys to include tokens, as long as they resolvable to strings. * __assert__: invoke `stack.validateTree()` by default for `expect(stack)` to simulate synthesis. ---- * Features not supported yet are listed here: #727, #723 * Fixes #602, copy: @hassankhan
1 parent 815915e commit b0f3857

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+5835
-136
lines changed

packages/@aws-cdk/applet-js/package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@aws-cdk/assert/lib/expect.ts

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,27 @@ import cdk = require('@aws-cdk/cdk');
22
import api = require('@aws-cdk/cx-api');
33
import { StackInspector } from './inspector';
44

5-
export function expect(stack: api.SynthesizedStack | cdk.Stack): StackInspector {
5+
export function expect(stack: api.SynthesizedStack | cdk.Stack, skipValidation = false): StackInspector {
66
// Can't use 'instanceof' here, that breaks if we have multiple copies
77
// of this library.
8-
const sstack: api.SynthesizedStack = isStackClassInstance(stack) ? {
9-
name: 'test',
10-
template: stack.toCloudFormation(),
11-
metadata: {}
12-
} : stack;
8+
let sstack: api.SynthesizedStack;
9+
10+
if (isStackClassInstance(stack)) {
11+
if (!skipValidation) {
12+
const errors = stack.validateTree();
13+
if (errors.length > 0) {
14+
throw new Error(`Stack validation failed:\n${errors.map(e => `${e.message} at: ${e.source.parent}`).join('\n')}`);
15+
}
16+
}
17+
18+
sstack = {
19+
name: 'test',
20+
template: stack.toCloudFormation(),
21+
metadata: {}
22+
};
23+
} else {
24+
sstack = stack;
25+
}
1326

1427
return new StackInspector(sstack);
1528
}

packages/@aws-cdk/assert/package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 165 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,165 @@
1-
## The CDK Construct Library for AWS API Gateway
2-
This module is part of the [AWS Cloud Development Kit](https://github.com/awslabs/aws-cdk) project.
1+
## CDK Construct Library for Amazon API Gateway
2+
3+
Amazon API Gateway is a fully managed service that makes it easy for developers
4+
to publish, maintain, monitor, and secure APIs at any scale. Create an API to
5+
access data, business logic, or functionality from your back-end services, such
6+
as applications running on Amazon Elastic Compute Cloud (Amazon EC2), code
7+
running on AWS Lambda, or any web application.
8+
9+
### Defining APIs
10+
11+
APIs are defined as a hierarchy of resources and methods. `addResource` and
12+
`addMethod` can be used to build this hierarchy. The root resource is
13+
`api.root`.
14+
15+
For example, the following code defines an API that includes the following HTTP
16+
endpoints: `ANY /, GET /books`, `POST /books`, `GET /books/{book_id}`, `DELETE /books/{book_id}`.
17+
18+
```ts
19+
const api = new apigateway.RestApi(this, 'books-api');
20+
21+
api.root.addMethod('ANY');
22+
23+
const books = api.root.addResource('books');
24+
books.addMethod('GET');
25+
books.addMethod('POST');
26+
27+
const book = books.addResource('{book_id}');
28+
book.addMethod('GET');
29+
book.addMethod('DELETE');
30+
```
31+
32+
### Integration Targets
33+
34+
Methods are associated with backend integrations, which are invoked when this
35+
method is called. API Gateway supports the following integrations:
36+
37+
* `MockIntegration` - can be used to test APIs. This is the default
38+
integration if one is not specified.
39+
* `LambdaIntegration` - can be used to invoke an AWS Lambda function.
40+
* `AwsIntegration` - can be used to invoke arbitrary AWS service APIs.
41+
* `HttpIntegration` - can be used to invoke HTTP endpoints.
42+
43+
The following example shows how to integrate the `GET /book/{book_id}` method to
44+
an AWS Lambda function:
45+
46+
```ts
47+
const getBookHandler = new lambda.Function(...);
48+
const getBookIntegration = new apigateway.LambdaIntegration(getBookHandler);
49+
book.addMethod('GET', getBookIntegration);
50+
```
51+
52+
Integration options can be optionally be specified:
53+
54+
```ts
55+
const getBookIntegration = new apigateway.LambdaIntegration(getBookHandler, {
56+
contentHandling: apigateway.ContentHandling.ConvertToText, // convert to base64
57+
credentialsPassthrough: true, // use caller identity to invoke the function
58+
});
59+
```
60+
61+
Method options can optionally be specified when adding methods:
62+
63+
```ts
64+
book.addMethod('GET', getBookIntegration, {
65+
authorizationType: apigateway.AuthorizationType.IAM,
66+
apiKeyRequired: true
67+
});
68+
```
69+
70+
#### Default Integration and Method Options
71+
72+
The `defaultIntegration` and `defaultMethodOptions` properties can be used to
73+
configure a default integration at any resource level. These options will be
74+
used when defining method under this resource (recursively) with undefined
75+
integration or options.
76+
77+
> If not defined, the default integration is `MockIntegration`. See reference
78+
documentation for default method options.
79+
80+
The following example defines the `booksBackend` integration as a default
81+
integration. This means that all API methods that do not explicitly define an
82+
integration will be routed to this AWS Lambda function.
83+
84+
```ts
85+
const booksBackend = new apigateway.LambdaIntegration(...);
86+
const api = new apigateway.RestApi(this, 'books', {
87+
defaultIntegration: booksBackend
88+
});
89+
90+
const books = new api.root.addResource('books');
91+
books.addMethod('GET'); // integrated with `booksBackend`
92+
books.addMethod('POST'); // integrated with `booksBackend`
93+
94+
const book = books.addResource('{book_id}');
95+
book.addMethod('GET'); // integrated with `booksBackend`
96+
```
97+
98+
### Deployments
99+
100+
By default, the `RestApi` construct will automatically create an API Gateway
101+
[Deployment] and a "prod" [Stage] which represent the API configuration you
102+
defined in your CDK app. This means that when you deploy your app, your API will
103+
be have open access from the internet via the stage URL.
104+
105+
The URL of your API can be obtained from the attribute `restApi.url`, and is
106+
also exported as an `Output` from your stack, so it's printed when you `cdk
107+
deploy` your app:
108+
109+
```
110+
$ cdk deploy
111+
...
112+
books.booksapiEndpointE230E8D5 = https://6lyktd4lpk.execute-api.us-east-1.amazonaws.com/prod/
113+
```
114+
115+
To disable this behavior, you can set `{ deploy: false }` when creating your
116+
API. This means that the API will not be deployed and a stage will not be
117+
created for it. You will need to manually define a `apigateway.Deployment` and
118+
`apigateway.Stage` resources.
119+
120+
Use the `deployOptions` property to customize the deployment options of your
121+
API.
122+
123+
The following example will configure API Gateway to emit logs and data traces to
124+
AWS CloudWatch for all API calls:
125+
126+
> By default, an IAM role will be created and associated with API Gateway to
127+
allow it to write logs and metrics to AWS CloudWatch `cloudWatchRole` is set to
128+
`false`.
129+
130+
```ts
131+
const api = new apigateway.RestApi(this, 'books', {
132+
deployOptions: {
133+
loggingLevel: apigateway.MethodLoggingLevel.Info,
134+
dataTraceEnabled: true
135+
}
136+
})
137+
```
138+
139+
#### Deeper dive: invalidation of deployments
140+
141+
API Gateway deployments are an immutable snapshot of the API. This means that we
142+
want to automatically create a new deployment resource every time the API model
143+
defined in our CDK app changes.
144+
145+
In order to achieve that, the AWS CloudFormation logical ID of the
146+
`AWS::ApiGateway::Deployment` resource is dynamically calculated by hashing the
147+
API configuration (resources, methods). This means that when the configuration
148+
changes (i.e. a resource or method are added, configuration is changed), a new
149+
logical ID will be assigned to the deployment resource. This will cause
150+
CloudFormation to create a new deployment resource.
151+
152+
By default, old deployments are _deleted_. You can set `retainDeployments: true`
153+
to allow users revert the stage to an old deployment manually.
154+
155+
[Deployment]: https://docs.aws.amazon.com/apigateway/api-reference/resource/deployment/
156+
[Stage]: https://docs.aws.amazon.com/apigateway/api-reference/resource/stage/
157+
158+
### Missing Features
159+
160+
See [awslabs/aws-cdk#723](https://github.com/awslabs/aws-cdk/issues/723) for a
161+
list of missing features.
162+
163+
----
164+
165+
This module is part of the [AWS Cloud Development Kit](https://github.com/awslabs/aws-cdk) project.

0 commit comments

Comments
 (0)