Skip to content

Commit

Permalink
feat(apigatewayv2): http api (#6432)
Browse files Browse the repository at this point in the history
Co-authored by: Niranjan Jayakar <nija@amazon.com>

closes #5301
  • Loading branch information
pahud committed May 4, 2020
1 parent 40fa93a commit f3219c3
Show file tree
Hide file tree
Showing 25 changed files with 1,526 additions and 10 deletions.
98 changes: 96 additions & 2 deletions packages/@aws-cdk/aws-apigatewayv2/README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,110 @@
## AWS::APIGatewayv2 Construct Library

<!--BEGIN STABILITY BANNER-->
---

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

> 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.
![cdk-constructs: Experimental](https://img.shields.io/badge/cdk--constructs-experimental-important.svg?style=for-the-badge)

> 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.
---
<!--END STABILITY BANNER-->

This module is part of the [AWS Cloud Development Kit](https://github.com/aws/aws-cdk) project.
## Table of Contents

- [Introduction](#introduction)
- [HTTP API](#http-api)
- [Defining HTTP APIs](#defining-http-apis)
- [Publishing HTTP APIs](#publishing-http-apis)

## Introduction

Amazon API Gateway is an AWS service for creating, publishing, maintaining, monitoring, and securing REST, HTTP, and WebSocket
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.
As an API Gateway API developer, you can create APIs for use in your own client applications. Read the
[Amazon API Gateway Developer Guide](https://docs.aws.amazon.com/apigateway/latest/developerguide/welcome.html).

This module supports features under [API Gateway v2](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/AWS_ApiGatewayV2.html)
that lets users set up Websocket and HTTP APIs.
REST APIs can be created using the `@aws-cdk/aws-apigateway` module.

## HTTP API

HTTP APIs enable creation of RESTful APIs that integrate with AWS Lambda functions, known as Lambda proxy integration,
or to any routable HTTP endpoint, known as HTTP proxy integration.

### Defining HTTP APIs

HTTP APIs have two fundamental concepts - Routes and Integrations.

Routes direct incoming API requests to backend resources. Routes consist of two parts: an HTTP method and a resource
path, such as, `GET /books`. Learn more at [Working with
routes](https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-develop-routes.html). Use the `ANY` method
to match any methods for a route that are not explicitly defined.

Integrations define how the HTTP API responds when a client reaches a specific Route. HTTP APIs support two types of
integrations - Lambda proxy integration and HTTP proxy integration. Learn more at [Configuring
integrations](https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-develop-integrations.html).

The code snippet below configures a route `GET /books` with an HTTP proxy integration and uses the `ANY` method to
proxy all other HTTP method calls to `/books` to a lambda proxy.

```ts
import * as apigatewayv2 from '@aws-cdk/aws-apigatewayv2';
const getBooksIntegration = new HttpProxyIntegration({
url: 'https://get-books-proxy.myproxy.internal',
});

const booksDefaultFn = new lambda.Function(stack, 'BooksDefaultFn', { ... });
const booksDefaultIntegration = new LambdaProxyIntegration({
handler: booksDefaultFn,
});

const httpApi = new HttpApi(stack, 'HttpApi');

httpApi.addRoutes({
path: '/books',
methods: [ HttpMethod.GET ],
integration: getBooksIntegration,
});
httpApi.addRoutes({
path: '/books',
methods: [ HttpMethod.ANY ],
integration: booksDefaultIntegration,
});
```

The `defaultIntegration` option while defining HTTP APIs lets you create a default catch-all integration that is
matched when a client reaches a route that is not explicitly defined.

```ts
new HttpApi(stack, 'HttpProxyApi', {
defaultIntegration: new HttpProxyIntegration({
url:'http://example.com',
}),
});
```

### Publishing HTTP APIs

A Stage is a logical reference to a lifecycle state of your API (for example, `dev`, `prod`, `beta`, or `v2`). API
stages are identified by their stage name. Each stage is a named reference to a deployment of the API made available for
client applications to call.

Use `HttpStage` to create a Stage resource for HTTP APIs. The following code sets up a Stage, whose URL is available at
`https://{api_id}.execute-api.{region}.amazonaws.com/beta`.

```ts
new HttpStage(stack, 'Stage', {
httpApi: api,
stageName: 'beta',
});
```

If you omit the `stageName` will create a `$default` stage. A `$default` stage is one that is served from the base of
the API's URL - `https://{api_id}.execute-api.{region}.amazonaws.com/`.

Note that, `HttpApi` will always creates a `$default` stage, unless the `createDefaultStage` property is unset.
3 changes: 3 additions & 0 deletions packages/@aws-cdk/aws-apigatewayv2/lib/common/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from './integration';
export * from './route';
export * from './stage';
12 changes: 12 additions & 0 deletions packages/@aws-cdk/aws-apigatewayv2/lib/common/integration.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { IResource } from '@aws-cdk/core';

/**
* Represents an integration to an API Route.
*/
export interface IIntegration extends IResource {
/**
* Id of the integration.
* @attribute
*/
readonly integrationId: string;
}
12 changes: 12 additions & 0 deletions packages/@aws-cdk/aws-apigatewayv2/lib/common/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { IResource } from '@aws-cdk/core';

/**
* Represents a route.
*/
export interface IRoute extends IResource {
/**
* Id of the Route
* @attribute
*/
readonly routeId: string;
}
30 changes: 30 additions & 0 deletions packages/@aws-cdk/aws-apigatewayv2/lib/common/stage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { IResource } from '@aws-cdk/core';

/**
* Represents a Stage.
*/
export interface IStage extends IResource {
/**
* The name of the stage; its primary identifier.
* @attribute
*/
readonly stageName: string;
}

/**
* Options required to create a new stage.
* Options that are common between HTTP and Websocket APIs.
*/
export interface CommonStageOptions {
/**
* The name of the stage. See `StageName` class for more details.
* @default '$default' the default stage of the API. This stage will have the URL at the root of the API endpoint.
*/
readonly stageName?: string;

/**
* Whether updates to an API automatically trigger a new deployment.
* @default false
*/
readonly autoDeploy?: boolean;
}
133 changes: 133 additions & 0 deletions packages/@aws-cdk/aws-apigatewayv2/lib/http/api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
import { Construct, IResource, Resource } from '@aws-cdk/core';
import { CfnApi, CfnApiProps } from '../apigatewayv2.generated';
import { IHttpRouteIntegration } from './integration';
import { BatchHttpRouteOptions, HttpMethod, HttpRoute, HttpRouteKey } from './route';
import { HttpStage, HttpStageOptions } from './stage';

/**
* Represents an HTTP API
*/
export interface IHttpApi extends IResource {
/**
* The identifier of this API Gateway HTTP API.
* @attribute
*/
readonly httpApiId: string;
}

/**
* Properties to initialize an instance of `HttpApi`.
*/
export interface HttpApiProps {
/**
* Name for the HTTP API resoruce
* @default - id of the HttpApi construct.
*/
readonly apiName?: string;

/**
* An integration that will be configured on the catch-all route ($default).
* @default - none
*/
readonly defaultIntegration?: IHttpRouteIntegration;

/**
* Whether a default stage and deployment should be automatically created.
* @default true
*/
readonly createDefaultStage?: boolean;
}

/**
* Options for the Route with Integration resoruce
*/
export interface AddRoutesOptions extends BatchHttpRouteOptions {
/**
* The path at which all of these routes are configured.
*/
readonly path: string;

/**
* The HTTP methods to be configured
* @default HttpMethod.ANY
*/
readonly methods?: HttpMethod[];
}

/**
* Create a new API Gateway HTTP API endpoint.
* @resource AWS::ApiGatewayV2::Api
*/
export class HttpApi extends Resource implements IHttpApi {
/**
* Import an existing HTTP API into this CDK app.
*/
public static fromApiId(scope: Construct, id: string, httpApiId: string): IHttpApi {
class Import extends Resource implements IHttpApi {
public readonly httpApiId = httpApiId;
}
return new Import(scope, id);
}

public readonly httpApiId: string;
private readonly defaultStage: HttpStage | undefined;

constructor(scope: Construct, id: string, props?: HttpApiProps) {
super(scope, id);

const apiName = props?.apiName ?? id;

const apiProps: CfnApiProps = {
name: apiName,
protocolType: 'HTTP',
};
const resource = new CfnApi(this, 'Resource', apiProps);
this.httpApiId = resource.ref;

if (props?.defaultIntegration) {
new HttpRoute(this, 'DefaultRoute', {
httpApi: this,
routeKey: HttpRouteKey.DEFAULT,
integration: props.defaultIntegration,
});
}

if (props?.createDefaultStage === undefined || props.createDefaultStage === true) {
this.defaultStage = new HttpStage(this, 'DefaultStage', {
httpApi: this,
autoDeploy: true,
});
}
}

/**
* Get the URL to the default stage of this API.
* Returns `undefined` if `createDefaultStage` is unset.
*/
public get url(): string | undefined {
return this.defaultStage ? this.defaultStage.url : undefined;
}

/**
* Add a new stage.
*/
public addStage(id: string, options: HttpStageOptions): HttpStage {
return new HttpStage(this, id, {
httpApi: this,
...options,
});
}

/**
* Add multiple routes that uses the same configuration. The routes all go to the same path, but for different
* methods.
*/
public addRoutes(options: AddRoutesOptions): HttpRoute[] {
const methods = options.methods ?? [ HttpMethod.ANY ];
return methods.map((method) => new HttpRoute(this, `${method}${options.path}`, {
httpApi: this,
routeKey: HttpRouteKey.with(options.path, method),
integration: options.integration,
}));
}
}
5 changes: 5 additions & 0 deletions packages/@aws-cdk/aws-apigatewayv2/lib/http/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export * from './api';
export * from './route';
export * from './integration';
export * from './integrations';
export * from './stage';

0 comments on commit f3219c3

Please sign in to comment.