UNPKG

49.3 kBMarkdownView Raw
1# Amazon API Gateway Construct Library
2<!--BEGIN STABILITY BANNER-->
3
4---
5
6![End-of-Support](https://img.shields.io/badge/End--of--Support-critical.svg?style=for-the-badge)
7
8> AWS CDK v1 has reached End-of-Support on 2023-06-01.
9> This package is no longer being updated, and users should migrate to AWS CDK v2.
10>
11> For more information on how to migrate, see the [_Migrating to AWS CDK v2_ guide][doc].
12>
13> [doc]: https://docs.aws.amazon.com/cdk/v2/guide/migrating-v2.html
14
15---
16
17<!--END STABILITY BANNER-->
18
19Amazon API Gateway is a fully managed service that makes it easy for developers
20to publish, maintain, monitor, and secure APIs at any scale. Create an API to
21access data, business logic, or functionality from your back-end services, such
22as applications running on Amazon Elastic Compute Cloud (Amazon EC2), code
23running on AWS Lambda, or any web application.
24
25## Table of Contents
26
27- [Defining APIs](#defining-apis)
28 - [Breaking up Methods and Resources across Stacks](#breaking-up-methods-and-resources-across-stacks)
29- [AWS Lambda-backed APIs](#aws-lambda-backed-apis)
30- [AWS StepFunctions backed APIs](#aws-stepfunctions-backed-APIs)
31- [Integration Targets](#integration-targets)
32- [Usage Plan & API Keys](#usage-plan--api-keys)
33- [Working with models](#working-with-models)
34- [Default Integration and Method Options](#default-integration-and-method-options)
35- [Proxy Routes](#proxy-routes)
36- [Authorizers](#authorizers)
37 - [IAM-based authorizer](#iam-based-authorizer)
38 - [Lambda-based token authorizer](#lambda-based-token-authorizer)
39 - [Lambda-based request authorizer](#lambda-based-request-authorizer)
40 - [Cognito User Pools authorizer](#cognito-user-pools-authorizer)
41- [Mutual TLS](#mutal-tls-mtls)
42- [Deployments](#deployments)
43 - [Deep dive: Invalidation of deployments](#deep-dive-invalidation-of-deployments)
44- [Custom Domains](#custom-domains)
45- [Access Logging](#access-logging)
46- [Cross Origin Resource Sharing (CORS)](#cross-origin-resource-sharing-cors)
47- [Endpoint Configuration](#endpoint-configuration)
48- [Private Integrations](#private-integrations)
49- [Gateway Response](#gateway-response)
50- [OpenAPI Definition](#openapi-definition)
51 - [Endpoint configuration](#endpoint-configuration)
52- [Metrics](#metrics)
53- [APIGateway v2](#apigateway-v2)
54
55## Defining APIs
56
57APIs are defined as a hierarchy of resources and methods. `addResource` and
58`addMethod` can be used to build this hierarchy. The root resource is
59`api.root`.
60
61For example, the following code defines an API that includes the following HTTP
62endpoints: `ANY /`, `GET /books`, `POST /books`, `GET /books/{book_id}`, `DELETE /books/{book_id}`.
63
64```ts
65const api = new apigateway.RestApi(this, 'books-api');
66
67api.root.addMethod('ANY');
68
69const books = api.root.addResource('books');
70books.addMethod('GET');
71books.addMethod('POST');
72
73const book = books.addResource('{book_id}');
74book.addMethod('GET');
75book.addMethod('DELETE');
76```
77
78## AWS Lambda-backed APIs
79
80A very common practice is to use Amazon API Gateway with AWS Lambda as the
81backend integration. The `LambdaRestApi` construct makes it easy:
82
83The following code defines a REST API that routes all requests to the
84specified AWS Lambda function:
85
86```ts
87declare const backend: lambda.Function;
88new apigateway.LambdaRestApi(this, 'myapi', {
89 handler: backend,
90});
91```
92
93You can also supply `proxy: false`, in which case you will have to explicitly
94define the API model:
95
96```ts
97declare const backend: lambda.Function;
98const api = new apigateway.LambdaRestApi(this, 'myapi', {
99 handler: backend,
100 proxy: false
101});
102
103const items = api.root.addResource('items');
104items.addMethod('GET'); // GET /items
105items.addMethod('POST'); // POST /items
106
107const item = items.addResource('{item}');
108item.addMethod('GET'); // GET /items/{item}
109
110// the default integration for methods is "handler", but one can
111// customize this behavior per method or even a sub path.
112item.addMethod('DELETE', new apigateway.HttpIntegration('http://amazon.com'));
113```
114
115## AWS StepFunctions backed APIs
116
117You can use Amazon API Gateway with AWS Step Functions as the backend integration, specifically Synchronous Express Workflows.
118
119The `StepFunctionsRestApi` only supports integration with Synchronous Express state machine. The `StepFunctionsRestApi` construct makes this easy by setting up input, output and error mapping.
120
121The construct sets up an API endpoint and maps the `ANY` HTTP method and any calls to the API endpoint starts an express workflow execution for the underlying state machine.
122
123Invoking the endpoint with any HTTP method (`GET`, `POST`, `PUT`, `DELETE`, ...) in the example below will send the request to the state machine as a new execution. On success, an HTTP code `200` is returned with the execution output as the Response Body.
124
125If the execution fails, an HTTP `500` response is returned with the `error` and `cause` from the execution output as the Response Body. If the request is invalid (ex. bad execution input) HTTP code `400` is returned.
126
127The response from the invocation contains only the `output` field from the
128[StartSyncExecution](https://docs.aws.amazon.com/step-functions/latest/apireference/API_StartSyncExecution.html#API_StartSyncExecution_ResponseSyntax) API.
129In case of failures, the fields `error` and `cause` are returned as part of the response.
130Other metadata such as billing details, AWS account ID and resource ARNs are not returned in the API response.
131
132By default, a `prod` stage is provisioned.
133
134In order to reduce the payload size sent to AWS Step Functions, `headers` are not forwarded to the Step Functions execution input. It is possible to choose whether `headers`, `requestContext`, `path`, `querystring`, and `authorizer` are included or not. By default, `headers` are excluded in all requests.
135
136More details about AWS Step Functions payload limit can be found at https://docs.aws.amazon.com/step-functions/latest/dg/limits-overview.html#service-limits-task-executions.
137
138The following code defines a REST API that routes all requests to the specified AWS StepFunctions state machine:
139
140```ts
141const stateMachineDefinition = new stepfunctions.Pass(this, 'PassState');
142
143const stateMachine: stepfunctions.IStateMachine = new stepfunctions.StateMachine(this, 'StateMachine', {
144 definition: stateMachineDefinition,
145 stateMachineType: stepfunctions.StateMachineType.EXPRESS,
146});
147
148new apigateway.StepFunctionsRestApi(this, 'StepFunctionsRestApi', {
149 deploy: true,
150 stateMachine: stateMachine,
151});
152```
153
154When the REST API endpoint configuration above is invoked using POST, as follows -
155
156```bash
157curl -X POST -d '{ "customerId": 1 }' https://example.com/
158```
159
160AWS Step Functions will receive the request body in its input as follows:
161
162```json
163{
164 "body": {
165 "customerId": 1
166 },
167 "path": "/",
168 "querystring": {}
169}
170```
171
172When the endpoint is invoked at path '/users/5' using the HTTP GET method as below:
173
174```bash
175curl -X GET https://example.com/users/5?foo=bar
176```
177
178AWS Step Functions will receive the following execution input:
179
180```json
181{
182 "body": {},
183 "path": {
184 "users": "5"
185 },
186 "querystring": {
187 "foo": "bar"
188 }
189}
190```
191
192Additional information around the request such as the request context, authorizer context, and headers can be included as part of the input
193forwarded to the state machine. The following example enables headers to be included in the input but not query string.
194
195```ts fixture=stepfunctions
196new apigateway.StepFunctionsRestApi(this, 'StepFunctionsRestApi', {
197 stateMachine: machine,
198 headers: true,
199 path: false,
200 querystring: false,
201 authorizer: false,
202 requestContext: {
203 caller: true,
204 user: true,
205 },
206});
207```
208
209In such a case, when the endpoint is invoked as below:
210
211```bash
212curl -X GET https://example.com/
213```
214
215AWS Step Functions will receive the following execution input:
216
217```json
218{
219 "headers": {
220 "Accept": "...",
221 "CloudFront-Forwarded-Proto": "...",
222 },
223 "requestContext": {
224 "accountId": "...",
225 "apiKey": "...",
226 },
227 "body": {}
228}
229```
230
231### Breaking up Methods and Resources across Stacks
232
233It is fairly common for REST APIs with a large number of Resources and Methods to hit the [CloudFormation
234limit](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cloudformation-limits.html) of 500 resources per
235stack.
236
237To help with this, Resources and Methods for the same REST API can be re-organized across multiple stacks. A common
238way to do this is to have a stack per Resource or groups of Resources, but this is not the only possible way.
239The following example uses sets up two Resources '/pets' and '/books' in separate stacks using nested stacks:
240
241[Resources grouped into nested stacks](test/integ.restapi-import.lit.ts)
242
243## Integration Targets
244
245Methods are associated with backend integrations, which are invoked when this
246method is called. API Gateway supports the following integrations:
247
248- `MockIntegration` - can be used to test APIs. This is the default
249 integration if one is not specified.
250- `LambdaIntegration` - can be used to invoke an AWS Lambda function.
251- `AwsIntegration` - can be used to invoke arbitrary AWS service APIs.
252- `HttpIntegration` - can be used to invoke HTTP endpoints.
253
254The following example shows how to integrate the `GET /book/{book_id}` method to
255an AWS Lambda function:
256
257```ts
258declare const getBookHandler: lambda.Function;
259declare const book: apigateway.Resource;
260
261const getBookIntegration = new apigateway.LambdaIntegration(getBookHandler);
262book.addMethod('GET', getBookIntegration);
263```
264
265Integration options can be optionally be specified:
266
267```ts
268declare const getBookHandler: lambda.Function;
269declare const getBookIntegration: apigateway.LambdaIntegration;
270
271const getBookIntegration = new apigateway.LambdaIntegration(getBookHandler, {
272 contentHandling: apigateway.ContentHandling.CONVERT_TO_TEXT, // convert to base64
273 credentialsPassthrough: true, // use caller identity to invoke the function
274});
275```
276
277Method options can optionally be specified when adding methods:
278
279```ts
280declare const book: apigateway.Resource;
281declare const getBookIntegration: apigateway.LambdaIntegration;
282
283book.addMethod('GET', getBookIntegration, {
284 authorizationType: apigateway.AuthorizationType.IAM,
285 apiKeyRequired: true
286});
287```
288
289It is possible to also integrate with AWS services in a different region. The following code integrates with Amazon SQS in the
290`eu-west-1` region.
291
292```ts
293const getMessageIntegration = new apigateway.AwsIntegration({
294 service: 'sqs',
295 path: 'queueName',
296 region: 'eu-west-1'
297});
298```
299
300## Usage Plan & API Keys
301
302A usage plan specifies who can access one or more deployed API stages and methods, and the rate at which they can be
303accessed. The plan uses API keys to identify API clients and meters access to the associated API stages for each key.
304Usage plans also allow configuring throttling limits and quota limits that are enforced on individual client API keys.
305
306The following example shows how to create and asscociate a usage plan and an API key:
307
308```ts
309declare const integration: apigateway.LambdaIntegration;
310
311const api = new apigateway.RestApi(this, 'hello-api');
312
313const v1 = api.root.addResource('v1');
314const echo = v1.addResource('echo');
315const echoMethod = echo.addMethod('GET', integration, { apiKeyRequired: true });
316
317const plan = api.addUsagePlan('UsagePlan', {
318 name: 'Easy',
319 throttle: {
320 rateLimit: 10,
321 burstLimit: 2
322 }
323});
324
325const key = api.addApiKey('ApiKey');
326plan.addApiKey(key);
327```
328
329To associate a plan to a given RestAPI stage:
330
331```ts
332declare const plan: apigateway.UsagePlan;
333declare const api: apigateway.RestApi;
334declare const echoMethod: apigateway.Method;
335
336plan.addApiStage({
337 stage: api.deploymentStage,
338 throttle: [
339 {
340 method: echoMethod,
341 throttle: {
342 rateLimit: 10,
343 burstLimit: 2
344 }
345 }
346 ]
347});
348```
349
350Existing usage plans can be imported into a CDK app using its id.
351
352```ts
353const importedUsagePlan = apigateway.UsagePlan.fromUsagePlanId(this, 'imported-usage-plan', '<usage-plan-key-id>');
354```
355
356The name and value of the API Key can be specified at creation; if not
357provided, a name and value will be automatically generated by API Gateway.
358
359```ts
360declare const api: apigateway.RestApi;
361const key = api.addApiKey('ApiKey', {
362 apiKeyName: 'myApiKey1',
363 value: 'MyApiKeyThatIsAtLeast20Characters',
364});
365```
366
367Existing API keys can also be imported into a CDK app using its id.
368
369```ts
370const importedKey = apigateway.ApiKey.fromApiKeyId(this, 'imported-key', '<api-key-id>');
371```
372
373The "grant" methods can be used to give prepackaged sets of permissions to other resources. The
374following code provides read permission to an API key.
375
376```ts
377declare const importedKey: apigateway.ApiKey;
378declare const lambdaFn: lambda.Function;
379importedKey.grantRead(lambdaFn);
380```
381
382### ⚠️ Multiple API Keys
383
384It is possible to specify multiple API keys for a given Usage Plan, by calling `usagePlan.addApiKey()`.
385
386When using multiple API keys, a past bug of the CDK prevents API key associations to a Usage Plan to be deleted.
387If the CDK app had the [feature flag] - `@aws-cdk/aws-apigateway:usagePlanKeyOrderInsensitiveId` - enabled when the API
388keys were created, then the app will not be affected by this bug.
389
390If this is not the case, you will need to ensure that the CloudFormation [logical ids] of the API keys that are not
391being deleted remain unchanged.
392Make note of the logical ids of these API keys before removing any, and set it as part of the `addApiKey()` method:
393
394```ts
395declare const usageplan: apigateway.UsagePlan;
396declare const apiKey: apigateway.ApiKey;
397
398usageplan.addApiKey(apiKey, {
399 overrideLogicalId: '...',
400});
401```
402
403[feature flag]: https://docs.aws.amazon.com/cdk/latest/guide/featureflags.html
404[logical ids]: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/resources-section-structure.html
405
406### Rate Limited API Key
407
408In scenarios where you need to create a single api key and configure rate limiting for it, you can use `RateLimitedApiKey`.
409This construct lets you specify rate limiting properties which should be applied only to the api key being created.
410The API key created has the specified rate limits, such as quota and throttles, applied.
411
412The following example shows how to use a rate limited api key :
413
414```ts
415declare const api: apigateway.RestApi;
416
417const key = new apigateway.RateLimitedApiKey(this, 'rate-limited-api-key', {
418 customerId: 'hello-customer',
419 resources: [api],
420 quota: {
421 limit: 10000,
422 period: apigateway.Period.MONTH
423 }
424});
425```
426
427## Working with models
428
429When you work with Lambda integrations that are not Proxy integrations, you
430have to define your models and mappings for the request, response, and integration.
431
432```ts
433const hello = new lambda.Function(this, 'hello', {
434 runtime: lambda.Runtime.NODEJS_14_X,
435 handler: 'hello.handler',
436 code: lambda.Code.fromAsset('lambda')
437});
438
439const api = new apigateway.RestApi(this, 'hello-api', { });
440const resource = api.root.addResource('v1');
441```
442
443You can define more parameters on the integration to tune the behavior of API Gateway
444
445```ts
446declare const hello: lambda.Function;
447
448const integration = new apigateway.LambdaIntegration(hello, {
449 proxy: false,
450 requestParameters: {
451 // You can define mapping parameters from your method to your integration
452 // - Destination parameters (the key) are the integration parameters (used in mappings)
453 // - Source parameters (the value) are the source request parameters or expressions
454 // @see: https://docs.aws.amazon.com/apigateway/latest/developerguide/request-response-data-mappings.html
455 'integration.request.querystring.who': 'method.request.querystring.who'
456 },
457 allowTestInvoke: true,
458 requestTemplates: {
459 // You can define a mapping that will build a payload for your integration, based
460 // on the integration parameters that you have specified
461 // Check: https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-mapping-template-reference.html
462 'application/json': JSON.stringify({ action: 'sayHello', pollId: "$util.escapeJavaScript($input.params('who'))" })
463 },
464 // This parameter defines the behavior of the engine is no suitable response template is found
465 passthroughBehavior: apigateway.PassthroughBehavior.NEVER,
466 integrationResponses: [
467 {
468 // Successful response from the Lambda function, no filter defined
469 // - the selectionPattern filter only tests the error message
470 // We will set the response status code to 200
471 statusCode: "200",
472 responseTemplates: {
473 // This template takes the "message" result from the Lambda function, and embeds it in a JSON response
474 // Check https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-mapping-template-reference.html
475 'application/json': JSON.stringify({ state: 'ok', greeting: '$util.escapeJavaScript($input.body)' })
476 },
477 responseParameters: {
478 // We can map response parameters
479 // - Destination parameters (the key) are the response parameters (used in mappings)
480 // - Source parameters (the value) are the integration response parameters or expressions
481 'method.response.header.Content-Type': "'application/json'",
482 'method.response.header.Access-Control-Allow-Origin': "'*'",
483 'method.response.header.Access-Control-Allow-Credentials': "'true'"
484 }
485 },
486 {
487 // For errors, we check if the error message is not empty, get the error data
488 selectionPattern: '(\n|.)+',
489 // We will set the response status code to 200
490 statusCode: "400",
491 responseTemplates: {
492 'application/json': JSON.stringify({ state: 'error', message: "$util.escapeJavaScript($input.path('$.errorMessage'))" })
493 },
494 responseParameters: {
495 'method.response.header.Content-Type': "'application/json'",
496 'method.response.header.Access-Control-Allow-Origin': "'*'",
497 'method.response.header.Access-Control-Allow-Credentials': "'true'"
498 }
499 }
500 ]
501});
502
503```
504
505You can define models for your responses (and requests)
506
507```ts
508declare const api: apigateway.RestApi;
509
510// We define the JSON Schema for the transformed valid response
511const responseModel = api.addModel('ResponseModel', {
512 contentType: 'application/json',
513 modelName: 'ResponseModel',
514 schema: {
515 schema: apigateway.JsonSchemaVersion.DRAFT4,
516 title: 'pollResponse',
517 type: apigateway.JsonSchemaType.OBJECT,
518 properties: {
519 state: { type: apigateway.JsonSchemaType.STRING },
520 greeting: { type: apigateway.JsonSchemaType.STRING }
521 }
522 }
523});
524
525// We define the JSON Schema for the transformed error response
526const errorResponseModel = api.addModel('ErrorResponseModel', {
527 contentType: 'application/json',
528 modelName: 'ErrorResponseModel',
529 schema: {
530 schema: apigateway.JsonSchemaVersion.DRAFT4,
531 title: 'errorResponse',
532 type: apigateway.JsonSchemaType.OBJECT,
533 properties: {
534 state: { type: apigateway.JsonSchemaType.STRING },
535 message: { type: apigateway.JsonSchemaType.STRING }
536 }
537 }
538});
539
540```
541
542And reference all on your method definition.
543
544```ts
545declare const integration: apigateway.LambdaIntegration;
546declare const resource: apigateway.Resource;
547declare const responseModel: apigateway.Model;
548declare const errorResponseModel: apigateway.Model;
549
550resource.addMethod('GET', integration, {
551 // We can mark the parameters as required
552 requestParameters: {
553 'method.request.querystring.who': true
554 },
555 // we can set request validator options like below
556 requestValidatorOptions: {
557 requestValidatorName: 'test-validator',
558 validateRequestBody: true,
559 validateRequestParameters: false
560 },
561 methodResponses: [
562 {
563 // Successful response from the integration
564 statusCode: '200',
565 // Define what parameters are allowed or not
566 responseParameters: {
567 'method.response.header.Content-Type': true,
568 'method.response.header.Access-Control-Allow-Origin': true,
569 'method.response.header.Access-Control-Allow-Credentials': true
570 },
571 // Validate the schema on the response
572 responseModels: {
573 'application/json': responseModel
574 }
575 },
576 {
577 // Same thing for the error responses
578 statusCode: '400',
579 responseParameters: {
580 'method.response.header.Content-Type': true,
581 'method.response.header.Access-Control-Allow-Origin': true,
582 'method.response.header.Access-Control-Allow-Credentials': true
583 },
584 responseModels: {
585 'application/json': errorResponseModel
586 }
587 }
588 ]
589});
590```
591
592Specifying `requestValidatorOptions` automatically creates the RequestValidator construct with the given options.
593However, if you have your RequestValidator already initialized or imported, use the `requestValidator` option instead.
594
595## Default Integration and Method Options
596
597The `defaultIntegration` and `defaultMethodOptions` properties can be used to
598configure a default integration at any resource level. These options will be
599used when defining method under this resource (recursively) with undefined
600integration or options.
601
602> If not defined, the default integration is `MockIntegration`. See reference
603documentation for default method options.
604
605The following example defines the `booksBackend` integration as a default
606integration. This means that all API methods that do not explicitly define an
607integration will be routed to this AWS Lambda function.
608
609```ts
610declare const booksBackend: apigateway.LambdaIntegration;
611const api = new apigateway.RestApi(this, 'books', {
612 defaultIntegration: booksBackend
613});
614
615const books = api.root.addResource('books');
616books.addMethod('GET'); // integrated with `booksBackend`
617books.addMethod('POST'); // integrated with `booksBackend`
618
619const book = books.addResource('{book_id}');
620book.addMethod('GET'); // integrated with `booksBackend`
621```
622
623A Method can be configured with authorization scopes. Authorization scopes are
624used in conjunction with an [authorizer that uses Amazon Cognito user
625pools](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-integrate-with-cognito.html#apigateway-enable-cognito-user-pool).
626Read more about authorization scopes
627[here](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigateway-method.html#cfn-apigateway-method-authorizationscopes).
628
629Authorization scopes for a Method can be configured using the `authorizationScopes` property as shown below -
630
631```ts
632declare const books: apigateway.Resource;
633
634books.addMethod('GET', new apigateway.HttpIntegration('http://amazon.com'), {
635 authorizationType: apigateway.AuthorizationType.COGNITO,
636 authorizationScopes: ['Scope1','Scope2']
637});
638```
639
640## Proxy Routes
641
642The `addProxy` method can be used to install a greedy `{proxy+}` resource
643on a path. By default, this also installs an `"ANY"` method:
644
645```ts
646declare const resource: apigateway.Resource;
647declare const handler: lambda.Function;
648const proxy = resource.addProxy({
649 defaultIntegration: new apigateway.LambdaIntegration(handler),
650
651 // "false" will require explicitly adding methods on the `proxy` resource
652 anyMethod: true // "true" is the default
653});
654```
655
656## Authorizers
657
658API Gateway [supports several different authorization types](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-control-access-to-api.html)
659that can be used for controlling access to your REST APIs.
660
661### IAM-based authorizer
662
663The following CDK code provides 'execute-api' permission to an IAM user, via IAM policies, for the 'GET' method on the `books` resource:
664
665```ts
666declare const books: apigateway.Resource;
667declare const iamUser: iam.User;
668
669const getBooks = books.addMethod('GET', new apigateway.HttpIntegration('http://amazon.com'), {
670 authorizationType: apigateway.AuthorizationType.IAM
671});
672
673iamUser.attachInlinePolicy(new iam.Policy(this, 'AllowBooks', {
674 statements: [
675 new iam.PolicyStatement({
676 actions: [ 'execute-api:Invoke' ],
677 effect: iam.Effect.ALLOW,
678 resources: [ getBooks.methodArn ]
679 })
680 ]
681}))
682```
683
684### Lambda-based token authorizer
685
686API Gateway also allows [lambda functions to be used as authorizers](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-use-lambda-authorizer.html).
687
688This module provides support for token-based Lambda authorizers. When a client makes a request to an API's methods configured with such
689an authorizer, API Gateway calls the Lambda authorizer, which takes the caller's identity as input and returns an IAM policy as output.
690A token-based Lambda authorizer (also called a token authorizer) receives the caller's identity in a bearer token, such as
691a JSON Web Token (JWT) or an OAuth token.
692
693API Gateway interacts with the authorizer Lambda function handler by passing input and expecting the output in a specific format.
694The event object that the handler is called with contains the `authorizationToken` and the `methodArn` from the request to the
695API Gateway endpoint. The handler is expected to return the `principalId` (i.e. the client identifier) and a `policyDocument` stating
696what the client is authorizer to perform.
697See [here](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-use-lambda-authorizer.html) for a detailed specification on
698inputs and outputs of the Lambda handler.
699
700The following code attaches a token-based Lambda authorizer to the 'GET' Method of the Book resource:
701
702```ts
703declare const authFn: lambda.Function;
704declare const books: apigateway.Resource;
705
706const auth = new apigateway.TokenAuthorizer(this, 'booksAuthorizer', {
707 handler: authFn
708});
709
710books.addMethod('GET', new apigateway.HttpIntegration('http://amazon.com'), {
711 authorizer: auth
712});
713```
714
715A full working example is shown below.
716
717[Full token authorizer example](test/authorizers/integ.token-authorizer.lit.ts).
718
719By default, the `TokenAuthorizer` looks for the authorization token in the request header with the key 'Authorization'. This can,
720however, be modified by changing the `identitySource` property.
721
722Authorizers can also be passed via the `defaultMethodOptions` property within the `RestApi` construct or the `Method` construct. Unless
723explicitly overridden, the specified defaults will be applied across all `Method`s across the `RestApi` or across all `Resource`s,
724depending on where the defaults were specified.
725
726### Lambda-based request authorizer
727
728This module provides support for request-based Lambda authorizers. When a client makes a request to an API's methods configured with such
729an authorizer, API Gateway calls the Lambda authorizer, which takes specified parts of the request, known as identity sources,
730as input and returns an IAM policy as output. A request-based Lambda authorizer (also called a request authorizer) receives
731the identity sources in a series of values pulled from the request, from the headers, stage variables, query strings, and the context.
732
733API Gateway interacts with the authorizer Lambda function handler by passing input and expecting the output in a specific format.
734The event object that the handler is called with contains the body of the request and the `methodArn` from the request to the
735API Gateway endpoint. The handler is expected to return the `principalId` (i.e. the client identifier) and a `policyDocument` stating
736what the client is authorizer to perform.
737See [here](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-use-lambda-authorizer.html) for a detailed specification on
738inputs and outputs of the Lambda handler.
739
740The following code attaches a request-based Lambda authorizer to the 'GET' Method of the Book resource:
741
742```ts
743declare const authFn: lambda.Function;
744declare const books: apigateway.Resource;
745
746const auth = new apigateway.RequestAuthorizer(this, 'booksAuthorizer', {
747 handler: authFn,
748 identitySources: [apigateway.IdentitySource.header('Authorization')]
749});
750
751books.addMethod('GET', new apigateway.HttpIntegration('http://amazon.com'), {
752 authorizer: auth
753});
754```
755
756A full working example is shown below.
757
758[Full request authorizer example](test/authorizers/integ.request-authorizer.lit.ts).
759
760By default, the `RequestAuthorizer` does not pass any kind of information from the request. This can,
761however, be modified by changing the `identitySource` property, and is required when specifying a value for caching.
762
763Authorizers can also be passed via the `defaultMethodOptions` property within the `RestApi` construct or the `Method` construct. Unless
764explicitly overridden, the specified defaults will be applied across all `Method`s across the `RestApi` or across all `Resource`s,
765depending on where the defaults were specified.
766
767### Cognito User Pools authorizer
768
769API Gateway also allows [Amazon Cognito user pools as authorizer](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-integrate-with-cognito.html)
770
771The following snippet configures a Cognito user pool as an authorizer:
772
773```ts
774const userPool = new cognito.UserPool(this, 'UserPool');
775
776const auth = new apigateway.CognitoUserPoolsAuthorizer(this, 'booksAuthorizer', {
777 cognitoUserPools: [userPool]
778});
779
780declare const books: apigateway.Resource;
781books.addMethod('GET', new apigateway.HttpIntegration('http://amazon.com'), {
782 authorizer: auth,
783 authorizationType: apigateway.AuthorizationType.COGNITO,
784});
785```
786
787## Mutual TLS (mTLS)
788
789Mutual TLS can be configured to limit access to your API based by using client certificates instead of (or as an extension of) using authorization headers.
790
791```ts
792declare const acm: any;
793
794new apigateway.DomainName(this, 'domain-name', {
795 domainName: 'example.com',
796 certificate: acm.Certificate.fromCertificateArn(this, 'cert', 'arn:aws:acm:us-east-1:1111111:certificate/11-3336f1-44483d-adc7-9cd375c5169d'),
797 mtls: {
798 bucket: new s3.Bucket(this, 'bucket'),
799 key: 'truststore.pem',
800 version: 'version',
801 },
802});
803```
804
805Instructions for configuring your trust store can be found [here](https://aws.amazon.com/blogs/compute/introducing-mutual-tls-authentication-for-amazon-api-gateway/).
806
807## Deployments
808
809By default, the `RestApi` construct will automatically create an API Gateway
810[Deployment] and a "prod" [Stage] which represent the API configuration you
811defined in your CDK app. This means that when you deploy your app, your API will
812be have open access from the internet via the stage URL.
813
814The URL of your API can be obtained from the attribute `restApi.url`, and is
815also exported as an `Output` from your stack, so it's printed when you `cdk
816deploy` your app:
817
818```console
819$ cdk deploy
820...
821books.booksapiEndpointE230E8D5 = https://6lyktd4lpk.execute-api.us-east-1.amazonaws.com/prod/
822```
823
824To disable this behavior, you can set `{ deploy: false }` when creating your
825API. This means that the API will not be deployed and a stage will not be
826created for it. You will need to manually define a `apigateway.Deployment` and
827`apigateway.Stage` resources.
828
829Use the `deployOptions` property to customize the deployment options of your
830API.
831
832The following example will configure API Gateway to emit logs and data traces to
833AWS CloudWatch for all API calls:
834
835> By default, an IAM role will be created and associated with API Gateway to
836allow it to write logs and metrics to AWS CloudWatch unless `cloudWatchRole` is
837set to `false`.
838
839```ts
840const api = new apigateway.RestApi(this, 'books', {
841 deployOptions: {
842 loggingLevel: apigateway.MethodLoggingLevel.INFO,
843 dataTraceEnabled: true
844 }
845})
846```
847
848### Deep dive: Invalidation of deployments
849
850API Gateway deployments are an immutable snapshot of the API. This means that we
851want to automatically create a new deployment resource every time the API model
852defined in our CDK app changes.
853
854In order to achieve that, the AWS CloudFormation logical ID of the
855`AWS::ApiGateway::Deployment` resource is dynamically calculated by hashing the
856API configuration (resources, methods). This means that when the configuration
857changes (i.e. a resource or method are added, configuration is changed), a new
858logical ID will be assigned to the deployment resource. This will cause
859CloudFormation to create a new deployment resource.
860
861By default, old deployments are _deleted_. You can set `retainDeployments: true`
862to allow users revert the stage to an old deployment manually.
863
864[Deployment]: https://docs.aws.amazon.com/apigateway/api-reference/resource/deployment/
865[Stage]: https://docs.aws.amazon.com/apigateway/api-reference/resource/stage/
866
867## Custom Domains
868
869To associate an API with a custom domain, use the `domainName` configuration when
870you define your API:
871
872```ts
873declare const acmCertificateForExampleCom: any;
874
875const api = new apigateway.RestApi(this, 'MyDomain', {
876 domainName: {
877 domainName: 'example.com',
878 certificate: acmCertificateForExampleCom,
879 },
880});
881```
882
883This will define a `DomainName` resource for you, along with a `BasePathMapping`
884from the root of the domain to the deployment stage of the API. This is a common
885set up.
886
887To route domain traffic to an API Gateway API, use Amazon Route 53 to create an
888alias record. An alias record is a Route 53 extension to DNS. It's similar to a
889CNAME record, but you can create an alias record both for the root domain, such
890as `example.com`, and for subdomains, such as `www.example.com`. (You can create
891CNAME records only for subdomains.)
892
893```ts
894import * as route53 from '@aws-cdk/aws-route53';
895import * as targets from '@aws-cdk/aws-route53-targets';
896
897declare const api: apigateway.RestApi;
898declare const hostedZoneForExampleCom: any;
899
900new route53.ARecord(this, 'CustomDomainAliasRecord', {
901 zone: hostedZoneForExampleCom,
902 target: route53.RecordTarget.fromAlias(new targets.ApiGateway(api))
903});
904```
905
906You can also define a `DomainName` resource directly in order to customize the default behavior:
907
908```ts
909declare const acmCertificateForExampleCom: any;
910
911new apigateway.DomainName(this, 'custom-domain', {
912 domainName: 'example.com',
913 certificate: acmCertificateForExampleCom,
914 endpointType: apigateway.EndpointType.EDGE, // default is REGIONAL
915 securityPolicy: apigateway.SecurityPolicy.TLS_1_2
916});
917```
918
919Once you have a domain, you can map base paths of the domain to APIs.
920The following example will map the URL <https://example.com/go-to-api1>
921to the `api1` API and <https://example.com/boom> to the `api2` API.
922
923```ts
924declare const domain: apigateway.DomainName;
925declare const api1: apigateway.RestApi;
926declare const api2: apigateway.RestApi;
927
928domain.addBasePathMapping(api1, { basePath: 'go-to-api1' });
929domain.addBasePathMapping(api2, { basePath: 'boom' });
930```
931
932You can specify the API `Stage` to which this base path URL will map to. By default, this will be the
933`deploymentStage` of the `RestApi`.
934
935```ts
936declare const domain: apigateway.DomainName;
937declare const restapi: apigateway.RestApi;
938
939const betaDeploy = new apigateway.Deployment(this, 'beta-deployment', {
940 api: restapi,
941});
942const betaStage = new apigateway.Stage(this, 'beta-stage', {
943 deployment: betaDeploy,
944});
945domain.addBasePathMapping(restapi, { basePath: 'api/beta', stage: betaStage });
946```
947
948If you don't specify `basePath`, all URLs under this domain will be mapped
949to the API, and you won't be able to map another API to the same domain:
950
951```ts
952declare const domain: apigateway.DomainName;
953declare const api: apigateway.RestApi;
954domain.addBasePathMapping(api);
955```
956
957This can also be achieved through the `mapping` configuration when defining the
958domain as demonstrated above.
959
960If you wish to setup this domain with an Amazon Route53 alias, use the `targets.ApiGatewayDomain`:
961
962```ts
963declare const hostedZoneForExampleCom: any;
964declare const domainName: apigateway.DomainName;
965
966import * as route53 from '@aws-cdk/aws-route53';
967import * as targets from '@aws-cdk/aws-route53-targets';
968
969new route53.ARecord(this, 'CustomDomainAliasRecord', {
970 zone: hostedZoneForExampleCom,
971 target: route53.RecordTarget.fromAlias(new targets.ApiGatewayDomain(domainName))
972});
973```
974
975## Access Logging
976
977Access logging creates logs every time an API method is accessed. Access logs can have information on
978who has accessed the API, how the caller accessed the API and what responses were generated.
979Access logs are configured on a Stage of the RestApi.
980Access logs can be expressed in a format of your choosing, and can contain any access details, with a
981minimum that it must include the 'requestId'. The list of variables that can be expressed in the access
982log can be found
983[here](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-mapping-template-reference.html#context-variable-reference).
984Read more at [Setting Up CloudWatch API Logging in API
985Gateway](https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-logging.html)
986
987```ts
988// production stage
989const prdLogGroup = new logs.LogGroup(this, "PrdLogs");
990const api = new apigateway.RestApi(this, 'books', {
991 deployOptions: {
992 accessLogDestination: new apigateway.LogGroupLogDestination(prdLogGroup),
993 accessLogFormat: apigateway.AccessLogFormat.jsonWithStandardFields()
994 }
995})
996const deployment = new apigateway.Deployment(this, 'Deployment', {api});
997
998// development stage
999const devLogGroup = new logs.LogGroup(this, "DevLogs");
1000new apigateway.Stage(this, 'dev', {
1001 deployment,
1002 accessLogDestination: new apigateway.LogGroupLogDestination(devLogGroup),
1003 accessLogFormat: apigateway.AccessLogFormat.jsonWithStandardFields({
1004 caller: false,
1005 httpMethod: true,
1006 ip: true,
1007 protocol: true,
1008 requestTime: true,
1009 resourcePath: true,
1010 responseLength: true,
1011 status: true,
1012 user: true
1013 })
1014});
1015```
1016
1017The following code will generate the access log in the [CLF format](https://en.wikipedia.org/wiki/Common_Log_Format).
1018
1019```ts
1020const logGroup = new logs.LogGroup(this, "ApiGatewayAccessLogs");
1021const api = new apigateway.RestApi(this, 'books', {
1022 deployOptions: {
1023 accessLogDestination: new apigateway.LogGroupLogDestination(logGroup),
1024 accessLogFormat: apigateway.AccessLogFormat.clf(),
1025 }});
1026```
1027
1028You can also configure your own access log format by using the `AccessLogFormat.custom()` API.
1029`AccessLogField` provides commonly used fields. The following code configures access log to contain.
1030
1031```ts
1032const logGroup = new logs.LogGroup(this, "ApiGatewayAccessLogs");
1033new apigateway.RestApi(this, 'books', {
1034 deployOptions: {
1035 accessLogDestination: new apigateway.LogGroupLogDestination(logGroup),
1036 accessLogFormat: apigateway.AccessLogFormat.custom(
1037 `${apigateway.AccessLogField.contextRequestId()} ${apigateway.AccessLogField.contextErrorMessage()} ${apigateway.AccessLogField.contextErrorMessageString()}`
1038 )
1039 }
1040});
1041```
1042
1043You can use the `methodOptions` property to configure
1044[default method throttling](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-request-throttling.html#apigateway-api-level-throttling-in-usage-plan)
1045for a stage. The following snippet configures the a stage that accepts
1046100 requests per minute, allowing burst up to 200 requests per minute.
1047
1048```ts
1049const api = new apigateway.RestApi(this, 'books');
1050const deployment = new apigateway.Deployment(this, 'my-deployment', { api });
1051const stage = new apigateway.Stage(this, 'my-stage', {
1052 deployment,
1053 methodOptions: {
1054 '/*/*': { // This special path applies to all resource paths and all HTTP methods
1055 throttlingRateLimit: 100,
1056 throttlingBurstLimit: 200
1057 }
1058 }
1059});
1060```
1061
1062Configuring `methodOptions` on the `deployOptions` of `RestApi` will set the
1063throttling behaviors on the default stage that is automatically created.
1064
1065```ts
1066const api = new apigateway.RestApi(this, 'books', {
1067 deployOptions: {
1068 methodOptions: {
1069 '/*/*': { // This special path applies to all resource paths and all HTTP methods
1070 throttlingRateLimit: 100,
1071 throttlingBurstLimit: 1000
1072 }
1073 }
1074 }
1075});
1076```
1077
1078## Cross Origin Resource Sharing (CORS)
1079
1080[Cross-Origin Resource Sharing (CORS)](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) is a mechanism
1081that uses additional HTTP headers to tell browsers to give a web application
1082running at one origin, access to selected resources from a different origin. A
1083web application executes a cross-origin HTTP request when it requests a resource
1084that has a different origin (domain, protocol, or port) from its own.
1085
1086You can add the CORS [preflight](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#Preflighted_requests) OPTIONS
1087HTTP method to any API resource via the `defaultCorsPreflightOptions` option or by calling the `addCorsPreflight` on a specific resource.
1088
1089The following example will enable CORS for all methods and all origins on all resources of the API:
1090
1091```ts
1092new apigateway.RestApi(this, 'api', {
1093 defaultCorsPreflightOptions: {
1094 allowOrigins: apigateway.Cors.ALL_ORIGINS,
1095 allowMethods: apigateway.Cors.ALL_METHODS // this is also the default
1096 }
1097})
1098```
1099
1100The following example will add an OPTIONS method to the `myResource` API resource, which
1101only allows GET and PUT HTTP requests from the origin <https://amazon.com.>
1102
1103```ts
1104declare const myResource: apigateway.Resource;
1105
1106myResource.addCorsPreflight({
1107 allowOrigins: [ 'https://amazon.com' ],
1108 allowMethods: [ 'GET', 'PUT' ]
1109});
1110```
1111
1112See the
1113[`CorsOptions`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-apigateway.CorsOptions.html)
1114API reference for a detailed list of supported configuration options.
1115
1116You can specify defaults this at the resource level, in which case they will be applied to the entire resource sub-tree:
1117
1118```ts
1119declare const resource: apigateway.Resource;
1120
1121const subtree = resource.addResource('subtree', {
1122 defaultCorsPreflightOptions: {
1123 allowOrigins: [ 'https://amazon.com' ]
1124 }
1125});
1126```
1127
1128This means that all resources under `subtree` (inclusive) will have a preflight
1129OPTIONS added to them.
1130
1131See [#906](https://github.com/aws/aws-cdk/issues/906) for a list of CORS
1132features which are not yet supported.
1133
1134## Endpoint Configuration
1135
1136API gateway allows you to specify an
1137[API Endpoint Type](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-api-endpoint-types.html).
1138To define an endpoint type for the API gateway, use `endpointConfiguration` property:
1139
1140```ts
1141const api = new apigateway.RestApi(this, 'api', {
1142 endpointConfiguration: {
1143 types: [ apigateway.EndpointType.EDGE ]
1144 }
1145});
1146```
1147
1148You can also create an association between your Rest API and a VPC endpoint. By doing so,
1149API Gateway will generate a new
1150Route53 Alias DNS record which you can use to invoke your private APIs. More info can be found
1151[here](https://docs.aws.amazon.com/apigateway/latest/developerguide/associate-private-api-with-vpc-endpoint.html).
1152
1153Here is an example:
1154
1155```ts
1156declare const someEndpoint: ec2.IVpcEndpoint;
1157
1158const api = new apigateway.RestApi(this, 'api', {
1159 endpointConfiguration: {
1160 types: [ apigateway.EndpointType.PRIVATE ],
1161 vpcEndpoints: [ someEndpoint ]
1162 }
1163});
1164```
1165
1166By performing this association, we can invoke the API gateway using the following format:
1167
1168```plaintext
1169https://{rest-api-id}-{vpce-id}.execute-api.{region}.amazonaws.com/{stage}
1170```
1171
1172## Private Integrations
1173
1174A private integration makes it simple to expose HTTP/HTTPS resources behind an
1175Amazon VPC for access by clients outside of the VPC. The private integration uses
1176an API Gateway resource of `VpcLink` to encapsulate connections between API
1177Gateway and targeted VPC resources.
1178The `VpcLink` is then attached to the `Integration` of a specific API Gateway
1179Method. The following code sets up a private integration with a network load
1180balancer -
1181
1182```ts
1183import * as elbv2 from '@aws-cdk/aws-elasticloadbalancingv2';
1184
1185const vpc = new ec2.Vpc(this, 'VPC');
1186const nlb = new elbv2.NetworkLoadBalancer(this, 'NLB', {
1187 vpc,
1188});
1189const link = new apigateway.VpcLink(this, 'link', {
1190 targets: [nlb],
1191});
1192
1193const integration = new apigateway.Integration({
1194 type: apigateway.IntegrationType.HTTP_PROXY,
1195 options: {
1196 connectionType: apigateway.ConnectionType.VPC_LINK,
1197 vpcLink: link,
1198 },
1199});
1200```
1201
1202The uri for the private integration, in the case of a VpcLink, will be set to the DNS name of
1203the VPC Link's NLB. If the VPC Link has multiple NLBs or the VPC Link is imported or the DNS
1204name cannot be determined for any other reason, the user is expected to specify the `uri`
1205property.
1206
1207Any existing `VpcLink` resource can be imported into the CDK app via the `VpcLink.fromVpcLinkId()`.
1208
1209```ts
1210const awesomeLink = apigateway.VpcLink.fromVpcLinkId(this, 'awesome-vpc-link', 'us-east-1_oiuR12Abd');
1211```
1212
1213## Gateway response
1214
1215If the Rest API fails to process an incoming request, it returns to the client an error response without forwarding the
1216request to the integration backend. API Gateway has a set of standard response messages that are sent to the client for
1217each type of error. These error responses can be configured on the Rest API. The list of Gateway responses that can be
1218configured can be found [here](https://docs.aws.amazon.com/apigateway/latest/developerguide/supported-gateway-response-types.html).
1219Learn more about [Gateway
1220Responses](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-gatewayResponse-definition.html).
1221
1222The following code configures a Gateway Response when the response is 'access denied':
1223
1224```ts
1225const api = new apigateway.RestApi(this, 'books-api');
1226api.addGatewayResponse('test-response', {
1227 type: apigateway.ResponseType.ACCESS_DENIED,
1228 statusCode: '500',
1229 responseHeaders: {
1230 'Access-Control-Allow-Origin': "test.com",
1231 'test-key': 'test-value'
1232 },
1233 templates: {
1234 'application/json': '{ "message": $context.error.messageString, "statusCode": "488", "type": "$context.error.responseType" }'
1235 }
1236});
1237```
1238
1239## OpenAPI Definition
1240
1241CDK supports creating a REST API by importing an OpenAPI definition file. It currently supports OpenAPI v2.0 and OpenAPI
1242v3.0 definition files. Read more about [Configuring a REST API using
1243OpenAPI](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-import-api.html).
1244
1245The following code creates a REST API using an external OpenAPI definition JSON file -
1246
1247```ts
1248declare const integration: apigateway.Integration;
1249
1250const api = new apigateway.SpecRestApi(this, 'books-api', {
1251 apiDefinition: apigateway.ApiDefinition.fromAsset('path-to-file.json')
1252});
1253
1254const booksResource = api.root.addResource('books')
1255booksResource.addMethod('GET', integration);
1256```
1257
1258It is possible to use the `addResource()` API to define additional API Gateway Resources.
1259
1260**Note:** Deployment will fail if a Resource of the same name is already defined in the Open API specification.
1261
1262**Note:** Any default properties configured, such as `defaultIntegration`, `defaultMethodOptions`, etc. will only be
1263applied to Resources and Methods defined in the CDK, and not the ones defined in the spec. Use the [API Gateway
1264extensions to OpenAPI](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-swagger-extensions.html)
1265to configure these.
1266
1267There are a number of limitations in using OpenAPI definitions in API Gateway. Read the [Amazon API Gateway important
1268notes for REST APIs](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-known-issues.html#api-gateway-known-issues-rest-apis)
1269for more details.
1270
1271**Note:** When starting off with an OpenAPI definition using `SpecRestApi`, it is not possible to configure some
1272properties that can be configured directly in the OpenAPI specification file. This is to prevent people duplication
1273of these properties and potential confusion.
1274
1275### Endpoint configuration
1276
1277By default, `SpecRestApi` will create an edge optimized endpoint.
1278
1279This can be modified as shown below:
1280
1281```ts
1282declare const apiDefinition: apigateway.ApiDefinition;
1283
1284const api = new apigateway.SpecRestApi(this, 'ExampleRestApi', {
1285 apiDefinition,
1286 endpointTypes: [apigateway.EndpointType.PRIVATE]
1287});
1288```
1289
1290**Note:** For private endpoints you will still need to provide the
1291[`x-amazon-apigateway-policy`](https://docs.aws.amazon.com/apigateway/latest/developerguide/openapi-extensions-policy.html) and
1292[`x-amazon-apigateway-endpoint-configuration`](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-swagger-extensions-endpoint-configuration.html)
1293in your openApi file.
1294
1295## Metrics
1296
1297The API Gateway service sends metrics around the performance of Rest APIs to Amazon CloudWatch.
1298These metrics can be referred to using the metric APIs available on the `RestApi` construct.
1299The APIs with the `metric` prefix can be used to get reference to specific metrics for this API. For example,
1300the method below refers to the client side errors metric for this API.
1301
1302```ts
1303const api = new apigateway.RestApi(this, 'my-api');
1304const clientErrorMetric = api.metricClientError();
1305```
1306
1307## APIGateway v2
1308
1309APIGateway v2 APIs are now moved to its own package named `aws-apigatewayv2`. For backwards compatibility, existing
1310APIGateway v2 "CFN resources" (such as `CfnApi`) that were previously exported as part of this package, are still
1311exported from here and have been marked deprecated. However, updates to these CloudFormation resources, such as new
1312properties and new resource types will not be available.
1313
1314Move to using `aws-apigatewayv2` to get the latest APIs and updates.
1315
1316----
1317
1318This module is part of the [AWS Cloud Development Kit](https://github.com/aws/aws-cdk) project.