Skip to content

Commit

Permalink
Add unit and integration tests, refine documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
Benjamin Giles committed Apr 15, 2020
1 parent a84c366 commit 0dcd6c5
Show file tree
Hide file tree
Showing 6 changed files with 223 additions and 136 deletions.
21 changes: 16 additions & 5 deletions packages/@aws-cdk/aws-apigateway/lib/apidefinition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,12 @@ import * as s3_assets from '@aws-cdk/aws-s3-assets';
import * as cdk from '@aws-cdk/core';
import { CfnRestApi } from './apigateway.generated';

/**
* Represents a API Gateway Swagger or OpenAPI specification.
*/
export abstract class APIDefinition {
/**
* Creates an API definition from a specification file in an S3 bucket
* @returns `APIDefinitionS3` associated with the specified S3 object.
* @param bucket The S3 bucket
* @param key The object key
Expand All @@ -15,6 +19,7 @@ export abstract class APIDefinition {
}

/**
* Creates an API definition from a string
* @returns `InlineAPIDefinition` with inline specification.
* @param code The actual API specification (limited to 4KiB)
*/
Expand Down Expand Up @@ -64,6 +69,9 @@ export abstract class APIDefinition {
}
}

/**
* Post-Binding Configuration for a CDK construct
*/
export interface APIDefinitionConfig {
/**
* The location of the specification in S3 (mutually exclusive with `inlineDefinition`).
Expand Down Expand Up @@ -121,7 +129,7 @@ export class InlineAPIDefinition extends APIDefinition {
throw new Error('Inline API definition cannot be empty');
}

if (definition.length > 4906) {
if (definition.length > 4096) {
throw new Error('API definition is too large, must be <= 4096 but is ' + definition.length);
}
}
Expand Down Expand Up @@ -156,20 +164,20 @@ export class AssetAPIDefinition extends APIDefinition {
});
}

if (this.asset.isZipArchive) {
if (this.asset?.isZipArchive) {
throw new Error(`Asset cannot be a .zip file or a directory (${this.path})`);
}

return {
s3Location: {
bucket: this.asset.s3BucketName,
key: this.asset.s3ObjectKey
bucket: this.asset?.s3BucketName,
key: this.asset?.s3ObjectKey
}
};
}

public bindToResource(resource: cdk.CfnResource, options: ResourceBindOptions = { }) {
if (!this.asset) {
if (this.asset === undefined) {
throw new Error('bindToResource() must be called after bind()');
}

Expand All @@ -180,6 +188,9 @@ export class AssetAPIDefinition extends APIDefinition {
}
}

/**
* Post-Synthesis options
*/
export interface ResourceBindOptions {
/**
* The name of the CloudFormation property to annotate with asset metadata.
Expand Down
4 changes: 2 additions & 2 deletions packages/@aws-cdk/aws-apigateway/lib/restapi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ export class RestApi extends Resource implements IRestApi {
parameters: props.parameters
});
this.node.defaultChild = resource;

props.apiDefinition?.bindToResource(resource);
this.restApiId = resource.ref;

this.configureDeployment(props);
Expand Down Expand Up @@ -411,7 +411,7 @@ export class RestApi extends Resource implements IRestApi {
* Performs validation of the REST API.
*/
protected validate() {
if (this.methods.length === 0) {
if (this.methods.length === 0 && this._apiDefinition === undefined) {
return [ 'The REST API doesn\'t contain any methods' ];
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
{
"Resources": {
"myapi4C7BF186": {
"Type": "AWS::ApiGateway::RestApi",
"Properties": {
"BodyS3Location": {
"Bucket": {
"Ref": "AssetParametersb4e546901387aeeb588eabec043d35a7fdbe4d304185ae7ab763bb3ae4e61d58S3BucketC3882222"
},
"Key": {
"Fn::Join": [
"",
[
{
"Fn::Select": [
0,
{
"Fn::Split": [
"||",
{
"Ref": "AssetParametersb4e546901387aeeb588eabec043d35a7fdbe4d304185ae7ab763bb3ae4e61d58S3VersionKey1FFB68C8"
}
]
}
]
},
{
"Fn::Select": [
1,
{
"Fn::Split": [
"||",
{
"Ref": "AssetParametersb4e546901387aeeb588eabec043d35a7fdbe4d304185ae7ab763bb3ae4e61d58S3VersionKey1FFB68C8"
}
]
}
]
}
]
]
}
},
"Name": "my-api"
}
},
"myapiDeployment92F2CB49": {
"Type": "AWS::ApiGateway::Deployment",
"Properties": {
"RestApiId": {
"Ref": "myapi4C7BF186"
},
"Description": "Automatically created by the RestApi construct"
}
},
"myapiDeploymentStageprod298F01AF": {
"Type": "AWS::ApiGateway::Stage",
"Properties": {
"RestApiId": {
"Ref": "myapi4C7BF186"
},
"DeploymentId": {
"Ref": "myapiDeployment92F2CB49"
},
"StageName": "prod"
}
},
"myapiCloudWatchRole095452E5": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Statement": [
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Principal": {
"Service": "apigateway.amazonaws.com"
}
}
],
"Version": "2012-10-17"
},
"ManagedPolicyArns": [
{
"Fn::Join": [
"",
[
"arn:",
{
"Ref": "AWS::Partition"
},
":iam::aws:policy/service-role/AmazonAPIGatewayPushToCloudWatchLogs"
]
]
}
]
}
},
"myapiAccountEC421A0A": {
"Type": "AWS::ApiGateway::Account",
"Properties": {
"CloudWatchRoleArn": {
"Fn::GetAtt": [
"myapiCloudWatchRole095452E5",
"Arn"
]
}
},
"DependsOn": [
"myapi4C7BF186"
]
}
},
"Outputs": {
"myapiEndpoint3628AFE3": {
"Value": {
"Fn::Join": [
"",
[
"https://",
{
"Ref": "myapi4C7BF186"
},
".execute-api.",
{
"Ref": "AWS::Region"
},
".",
{
"Ref": "AWS::URLSuffix"
},
"/",
{
"Ref": "myapiDeploymentStageprod298F01AF"
},
"/"
]
]
}
}
},
"Parameters": {
"AssetParametersb4e546901387aeeb588eabec043d35a7fdbe4d304185ae7ab763bb3ae4e61d58S3BucketC3882222": {
"Type": "String",
"Description": "S3 bucket for asset \"b4e546901387aeeb588eabec043d35a7fdbe4d304185ae7ab763bb3ae4e61d58\""
},
"AssetParametersb4e546901387aeeb588eabec043d35a7fdbe4d304185ae7ab763bb3ae4e61d58S3VersionKey1FFB68C8": {
"Type": "String",
"Description": "S3 key for asset version \"b4e546901387aeeb588eabec043d35a7fdbe4d304185ae7ab763bb3ae4e61d58\""
},
"AssetParametersb4e546901387aeeb588eabec043d35a7fdbe4d304185ae7ab763bb3ae4e61d58ArtifactHash1A35D17D": {
"Type": "String",
"Description": "Artifact hash for asset \"b4e546901387aeeb588eabec043d35a7fdbe4d304185ae7ab763bb3ae4e61d58\""
}
}
}
119 changes: 19 additions & 100 deletions packages/@aws-cdk/aws-apigateway/test/sample-definition.yaml
Original file line number Diff line number Diff line change
@@ -1,111 +1,30 @@
openapi: "3.0.0"
openapi: "3.0.2"
info:
version: 1.0.0
title: Swagger Petstore
license:
name: MIT
servers:
- url: http://petstore.swagger.io/v1
title: Test API for CDK
paths:
/pets:
/testing:
get:
summary: List all pets
operationId: listPets
tags:
- pets
parameters:
- name: limit
in: query
description: How many items to return at one time (max 100)
required: false
schema:
type: integer
format: int32
summary: Test Method
operationId: testMethod
responses:
'200':
"200":
description: A paged array of pets
headers:
x-next:
description: A link to the next page of responses
schema:
type: string
content:
application/json:
schema:
$ref: "#/components/schemas/Pets"
default:
description: unexpected error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
post:
summary: Create a pet
operationId: createPets
tags:
- pets
responses:
'201':
description: Null response
default:
description: unexpected error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
/pets/{petId}:
get:
summary: Info for a specific pet
operationId: showPetById
tags:
- pets
parameters:
- name: petId
in: path
required: true
description: The id of the pet to retrieve
schema:
type: string
responses:
'200':
description: Expected response to a valid request
content:
application/json:
schema:
$ref: "#/components/schemas/Pet"
default:
description: unexpected error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
$ref: "#/components/schemas/Empty"
x-amazon-apigateway-integration:
responses:
default:
statusCode: "200"
requestTemplates:
application/json: "{\"statusCode\": 200}"
passthroughBehavior: when_no_match
type: mock

components:
schemas:
Pet:
type: object
required:
- id
- name
properties:
id:
type: integer
format: int64
name:
type: string
tag:
type: string
Pets:
type: array
items:
$ref: "#/components/schemas/Pet"
Error:
type: object
required:
- code
- message
properties:
code:
type: integer
format: int32
message:
type: string
Empty:
title: Empty Schema
type: object

0 comments on commit 0dcd6c5

Please sign in to comment.