Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(apigatewayv2): http api - custom domain & stage mapping #8027

Merged
merged 58 commits into from
Jul 6, 2020
Merged
Show file tree
Hide file tree
Changes from 41 commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
6f08839
- support custom domain
pahud May 16, 2020
2c4609e
revert
pahud May 16, 2020
ef071cb
Merge branch 'master' into httpapi-customdomain
pahud May 16, 2020
f64533a
minor fix
pahud May 16, 2020
0b84691
update REAdME
pahud May 16, 2020
a59e85d
update REAdME
pahud May 16, 2020
5538a75
minor update
pahud May 16, 2020
80d9cd9
minor update
pahud May 16, 2020
54ac53f
Merge branch 'master' into httpapi-customdomain
pahud May 16, 2020
d774cd8
remove comments
pahud May 16, 2020
edb90e1
remove comments
pahud May 16, 2020
e19482d
add domainName property for the HttpApi resource
pahud May 17, 2020
3d60e6b
minor update
pahud May 17, 2020
02c4654
move to common
pahud May 21, 2020
cb2205a
Merge branch 'master' into httpapi-customdomain
pahud May 21, 2020
9fb0d6d
Update packages/@aws-cdk/aws-apigatewayv2/lib/http/api-mapping.ts
pahud May 27, 2020
c0dc738
Merge branch 'master' into httpapi-customdomain
pahud May 27, 2020
7ae94b5
fix
pahud May 28, 2020
d79d455
Merge branch 'httpapi-customdomain' of github.com:pahud/aws-cdk into …
pahud Jun 3, 2020
0e23173
add defaultDomainMapping support and allow add `domainMapping` with a…
pahud Jun 3, 2020
09c8d22
Merge branch 'master' into httpapi-customdomain
pahud Jun 3, 2020
a2c94f0
remove domainNameId
pahud Jun 3, 2020
88e38c4
Merge branch 'httpapi-customdomain' of github.com:pahud/aws-cdk into …
pahud Jun 3, 2020
91b0394
Update packages/@aws-cdk/aws-apigatewayv2/README.md
pahud Jun 5, 2020
785aab5
Update packages/@aws-cdk/aws-apigatewayv2/README.md
pahud Jun 5, 2020
2722390
Update packages/@aws-cdk/aws-apigatewayv2/README.md
pahud Jun 5, 2020
db470f1
Update packages/@aws-cdk/aws-apigatewayv2/README.md
pahud Jun 5, 2020
c2da25e
Update packages/@aws-cdk/aws-apigatewayv2/README.md
pahud Jun 5, 2020
7ad257e
fix
pahud Jun 12, 2020
ceca681
Merge branch 'httpapi-customdomain' of github.com:pahud/aws-cdk into …
pahud Jun 12, 2020
38edd93
Merge branch 'master' into httpapi-customdomain
pahud Jun 12, 2020
43a586f
minor
pahud Jun 13, 2020
645f70d
Merge branch 'httpapi-customdomain' of github.com:pahud/aws-cdk into …
pahud Jun 13, 2020
7a2efda
Merge branch 'master' into httpapi-customdomain
pahud Jun 13, 2020
048f878
Update packages/@aws-cdk/aws-apigatewayv2/lib/common/api-mapping.ts
pahud Jun 13, 2020
ef20d1c
Update packages/@aws-cdk/aws-apigatewayv2/lib/common/domain-name.ts
pahud Jun 13, 2020
c59ec7f
Update packages/@aws-cdk/aws-apigatewayv2/lib/common/domain-name.ts
pahud Jun 13, 2020
f4bafaa
Update packages/@aws-cdk/aws-apigatewayv2/lib/http/api-mapping.ts
pahud Jun 13, 2020
989e774
Update packages/@aws-cdk/aws-apigatewayv2/lib/http/api-mapping.ts
pahud Jun 13, 2020
b63732a
minor
pahud Jun 13, 2020
6487866
minor fix
pahud Jun 13, 2020
0d7f114
Merge branch 'master' into httpapi-customdomain
pahud Jun 29, 2020
6564ced
Update packages/@aws-cdk/aws-apigatewayv2/README.md
pahud Jun 29, 2020
6256b8f
Update packages/@aws-cdk/aws-apigatewayv2/README.md
pahud Jun 29, 2020
08bd397
Update packages/@aws-cdk/aws-apigatewayv2/README.md
pahud Jun 29, 2020
56d62a6
Update packages/@aws-cdk/aws-apigatewayv2/README.md
pahud Jun 29, 2020
250e508
Update packages/@aws-cdk/aws-apigatewayv2/lib/http/api.ts
pahud Jun 29, 2020
35a8795
fix
pahud Jun 29, 2020
c22125f
fix
pahud Jun 29, 2020
993f448
Merge branch 'master' into httpapi-customdomain
pahud Jun 29, 2020
3c871d7
Update packages/@aws-cdk/aws-apigatewayv2/lib/http/api-mapping.ts
pahud Jul 3, 2020
9acaff1
Update packages/@aws-cdk/aws-apigatewayv2/lib/http/api-mapping.ts
pahud Jul 3, 2020
8c4f8c5
fix
pahud Jul 3, 2020
09c4003
Merge branch 'httpapi-customdomain' of github.com:pahud/aws-cdk into …
pahud Jul 3, 2020
0f77a40
fix
pahud Jul 3, 2020
6844bb6
fix
pahud Jul 3, 2020
5b5cf49
minor adjustments
Jul 6, 2020
4fa394c
Merge branch 'master' into httpapi-customdomain
mergify[bot] Jul 6, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions packages/@aws-cdk/aws-apigatewayv2/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
- [Defining HTTP APIs](#defining-http-apis)
- [Cross Origin Resource Sharing (CORS)](#cross-origin-resource-sharing-cors)
- [Publishing HTTP APIs](#publishing-http-apis)
- [Custom Domain](#custom-domain)

## Introduction

Expand Down Expand Up @@ -134,3 +135,67 @@ If you omit the `stageName` will create a `$default` stage. A `$default` stage i
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.



### Custom Domain Name
pahud marked this conversation as resolved.
Show resolved Hide resolved
pahud marked this conversation as resolved.
Show resolved Hide resolved

Custom domain names are simpler and more intuitive URLs that you can provide to your API users. Custom domains name are associated to API stages.
pahud marked this conversation as resolved.
Show resolved Hide resolved

The code snippet below creates a custom domain and configures a default domain mapping for your API that maps the
custom domain to the `$default` stage of the API.

```ts
const certArn = 'arn:aws:acm:us-east-1:111111111111:certificate';
const domainName = 'example.com';

const dn = new DomainName(stack, 'DN', {
domainName,
certificate: acm.Certificate.fromCertificateArn(stack, 'cert', certArn),
});

const api = new HttpApi(stack, 'HttpProxyProdApi', {
defaultIntegration: new LambdaProxyIntegration({ handler }),
// https://${dn.domainName} goes to prodApi $default stage
defaultDomainMapping: {
domainName: dn,
},
});
```

To associate a specifc `Stage` to a custom domain mapping -

```ts
api.addStage('beta', {
stageName: 'beta',
autoDeploy: true,
// https://${dn.domainName}/beta goes to prodApi beta stage
pahud marked this conversation as resolved.
Show resolved Hide resolved
domainMapping: {
domainName: dn,
mappingKey: 'beta',
},
} );
pahud marked this conversation as resolved.
Show resolved Hide resolved
```

The same domain name can be associated with stages across different `HttpApi` as so -

```ts
const apiDemo = new HttpApi(stack, 'DemoApi', {
defaultIntegration: new LambdaProxyIntegration({ handler }),
// https://${dn.domainName}/demo goes to apiDemo $default stage
defaultDomainMapping: {
domainName: dn,
mappingKey: 'demo',
},
});
```

The optional `mappingKey` determines the `path` of the URL with the custom domain. Each custom domain is only allowed
to have one API mapping with empty `mappingKey`. In the sample above, the custom domain is associated with 3 API
mapping resources across different APIs and Stages.

| API | Stage | URL |
| :------------: | :---------: | :----: |
| api | $default | `https://${domainName}` |
| api | beta | `https://${domainName}/beta` |
| apiDemo | $default | `https://${domainName}/demo` |
13 changes: 13 additions & 0 deletions packages/@aws-cdk/aws-apigatewayv2/lib/common/api-mapping.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { IResource } from '@aws-cdk/core';

/**
* Represents an ApiGatewayV2 ApiMapping resource
* @see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigatewayv2-apimapping.html
*/
export interface IApiMapping extends IResource {
/**
* ID of the api mapping
* @attribute
*/
readonly apiMappingId: string;
}
158 changes: 158 additions & 0 deletions packages/@aws-cdk/aws-apigatewayv2/lib/common/domain-name.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
import { ICertificate } from '@aws-cdk/aws-certificatemanager';
import { Construct, IResource, Resource } from '@aws-cdk/core';
import { CfnDomainName, CfnDomainNameProps } from '../apigatewayv2.generated';
import { IStage } from './stage';

/**
* Represents an APIGatewayV2 DomainName
* @see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigatewayv2-domainname.html
*/
export interface IDomainName extends IResource {
/**
* The custom domain name
*
* @attribute
*
*/
readonly domainName: string;

/**
* The domain name associated with the regional endpoint for this custom domain name.
*
* @attribute
*/
readonly regionalDomainName: string;

/**
* The region-specific Amazon Route 53 Hosted Zone ID of the regional endpoint.
*
* @attribute
*/
readonly regionalHostedZoneId: string;
}

/**
* custom domain name attributes
*/
export interface DomainNameAttributes {
/**
* domain name string
*/
readonly domainName: string;

/**
* The domain name associated with the regional endpoint for this custom domain name.
*/
readonly regionalDomainName: string;

/**
* The region-specific Amazon Route 53 Hosted Zone ID of the regional endpoint.
*/
readonly regionalHostedZoneId: string;
}

/**
* Options for defaultDomainMapping
*/
export interface DefaultDomainMappingOptions {
/**
* The domain name for the mapping
*
*/
readonly domainName: IDomainName;

/**
* The API mapping key
*
* @default - empty key
*/
readonly mappingKey?: string;

}

/**
* Options for DomainMapping
*/
export interface DomainMappingOptions extends DefaultDomainMappingOptions {
/**
* The API Stage
*
* @default - the $default stage
*/
readonly stage?: IStage;
}
pahud marked this conversation as resolved.
Show resolved Hide resolved

/**
* properties used for creating the DomainName
*/
export interface DomainNameProps {
/**
* The custom domain name
*/
readonly domainName: string;
/**
* The ACM certificate for this domain name
*/
readonly certificate: ICertificate;
}

/**
* Custom domain resource for the API
*/
export class DomainName extends Resource implements IDomainName {
/**
* import from attributes
*/
public static fromDomainNameAttributes(scope: Construct, id: string, attrs: DomainNameAttributes): IDomainName {
class Import extends Resource implements IDomainName {
public readonly regionalDomainName = attrs.regionalDomainName;
public readonly regionalHostedZoneId = attrs.regionalHostedZoneId;
public readonly domainName = attrs.domainName;
}
return new Import(scope, id);
}

/**
* the logical ID of the domain name
*
* @attribute
*/
public readonly domainNameId: string;

/**
* The custom domain name for your API in Amazon API Gateway.
*
* @attribute
*/
public readonly domainName: string;
pahud marked this conversation as resolved.
Show resolved Hide resolved

/**
* The domain name associated with the regional endpoint for this custom domain name.
*/
public readonly regionalDomainName: string;

/**
* The region-specific Amazon Route 53 Hosted Zone ID of the regional endpoint.
*/
public readonly regionalHostedZoneId: string;

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

this.domainName = props.domainName;

const domainNameProps: CfnDomainNameProps = {
domainName: props.domainName,
domainNameConfigurations: [
{
certificateArn: props.certificate.certificateArn,
endpointType: 'REGIONAL',
},
],
};
const resource = new CfnDomainName(this, 'Resource', domainNameProps);
this.domainNameId = resource.ref;
this.regionalDomainName = resource.getAtt('RegionalDomainName').toString();
this.regionalHostedZoneId = resource.getAtt('RegionalHostedZoneId').toString();
pahud marked this conversation as resolved.
Show resolved Hide resolved
}
}
4 changes: 3 additions & 1 deletion packages/@aws-cdk/aws-apigatewayv2/lib/common/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
export * from './integration';
export * from './route';
export * from './stage';
export * from './stage';
export * from './domain-name';
export * from './api-mapping';
92 changes: 92 additions & 0 deletions packages/@aws-cdk/aws-apigatewayv2/lib/http/api-mapping.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import { Construct, Resource } from '@aws-cdk/core';
import { CfnApiMapping, CfnApiMappingProps } from '../apigatewayv2.generated';
import { IApiMapping, IDomainName } from '../common';
import { IHttpApi } from '../http/api';
import { IHttpStage } from './stage';

/**
* Properties used to create the HttpApiMapping resource
*/
export interface HttpApiMappingProps {
/**
* Api mapping name
* @default - logical id
*/
readonly apiMappingName?: string;
pahud marked this conversation as resolved.
Show resolved Hide resolved

/**
* Api mapping key
* @default - empty api mapping key
*/
readonly apiMappingKey?: string;
pahud marked this conversation as resolved.
Show resolved Hide resolved

/**
* The HttpApi to which this mapping is applied
*/
readonly api: IHttpApi;

/**
* custom domain name of the mapping target
*/
readonly domainName: IDomainName;

/**
* stage for the HttpApiMapping resource
*
* @default - the $default stage
*/
readonly stage?: IHttpStage;
}

/**
* The attributes used to import existing HttpApiMapping
*/
export interface HttpApiMappingAttributes {
/**
* The API mapping ID
*/
readonly apiMappingId: string;
}

/**
* Create a new API mapping for API Gateway HTTP API endpoint.
* @resource AWS::ApiGatewayV2::ApiMapping
*/
export class HttpApiMapping extends Resource implements IApiMapping {
/**
* import from API ID
*/
public static fromHttpApiMappingAttributes(scope: Construct, id: string, attrs: HttpApiMappingAttributes): IApiMapping {
class Import extends Resource implements IApiMapping {
public readonly apiMappingId = attrs.apiMappingId;
}
return new Import(scope, id);
}
/**
* ID of the API Mapping
*/
public readonly apiMappingId: string;

/**
* Name of the API Mapping
* @attribute
*/
public readonly apiMappingName: string;

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

this.apiMappingName = props.apiMappingName ?? id;
pahud marked this conversation as resolved.
Show resolved Hide resolved

const apiMappingProps: CfnApiMappingProps = {
apiId: props.api.httpApiId,
domainName: props.domainName.domainName,
stage: props.stage ? props.stage.stageName : '$default',
pahud marked this conversation as resolved.
Show resolved Hide resolved
apiMappingKey: props.apiMappingKey,
};

const resource = new CfnApiMapping(this, 'Resource', apiMappingProps);
this.apiMappingId = resource.ref;
}

}
Loading