From ddcb89f77c25bdea4acb7444f42360fbbd9145b7 Mon Sep 17 00:00:00 2001 From: Rico Huijbers Date: Fri, 18 Jan 2019 10:18:50 +0100 Subject: [PATCH] Add support for MethodResponse to aws-apigateway. Remove Dockerfile that was no longer needed Update python base image from 3.6 to 3.6.5 Make the dockerfile work Add MethodResponse support for aws-apigateway Remove Dockerfile that was no longer needed Update python base image from 3.6 to 3.6.5 Make the dockerfile work Add MethodResponse to API Gateway Method. Add some documentation to the MethodResponse properties. Update the test for MethodResponse with response models. Fix some formatting and finish adding code documentation for MethodResponse. Remove Dockerfile from this branch Fix bad merge to methodresponse test. Correct the MethodResponse response models documentation. Add IModel type to reference when configuring a MethodResponse Slight update to comments. --- packages/@aws-cdk/aws-apigateway/lib/index.ts | 2 + .../@aws-cdk/aws-apigateway/lib/method.ts | 38 +++++++++++- .../aws-apigateway/lib/methodresponse.ts | 25 ++++++++ packages/@aws-cdk/aws-apigateway/lib/model.ts | 13 ++++ .../aws-apigateway/test/test.method.ts | 59 ++++++++++++++++++- 5 files changed, 134 insertions(+), 3 deletions(-) create mode 100644 packages/@aws-cdk/aws-apigateway/lib/methodresponse.ts create mode 100644 packages/@aws-cdk/aws-apigateway/lib/model.ts diff --git a/packages/@aws-cdk/aws-apigateway/lib/index.ts b/packages/@aws-cdk/aws-apigateway/lib/index.ts index 1ccd62b520805..b303ae6f4e243 100644 --- a/packages/@aws-cdk/aws-apigateway/lib/index.ts +++ b/packages/@aws-cdk/aws-apigateway/lib/index.ts @@ -7,6 +7,8 @@ export * from './stage'; export * from './integrations'; export * from './lambda-api'; export * from './vpc-link'; +export * from './methodresponse'; +export * from './model'; // AWS::ApiGateway CloudFormation Resources: export * from './apigateway.generated'; diff --git a/packages/@aws-cdk/aws-apigateway/lib/method.ts b/packages/@aws-cdk/aws-apigateway/lib/method.ts index cb263bc5083cc..6f41fd9240e74 100644 --- a/packages/@aws-cdk/aws-apigateway/lib/method.ts +++ b/packages/@aws-cdk/aws-apigateway/lib/method.ts @@ -2,6 +2,7 @@ import cdk = require('@aws-cdk/cdk'); import { CfnMethod, CfnMethodProps } from './apigateway.generated'; import { ConnectionType, Integration } from './integration'; import { MockIntegration } from './integrations/mock'; +import { MethodResponse } from './methodresponse'; import { IRestApiResource } from './resource'; import { RestApi } from './restapi'; import { validateHttpMethod } from './util'; @@ -34,11 +35,15 @@ export interface MethodOptions { */ apiKeyRequired?: boolean; + /** + * The responses that can be sent to the client who calls the method. + */ + methodResponses?: MethodResponse[] + // TODO: // - RequestValidatorId // - RequestModels // - RequestParameters - // - MethodResponses requestParameters?: { [param: string]: boolean }; } @@ -93,7 +98,8 @@ export class Method extends cdk.Construct { authorizationType: options.authorizationType || defaultMethodOptions.authorizationType || AuthorizationType.None, authorizerId: options.authorizerId || defaultMethodOptions.authorizerId, requestParameters: options.requestParameters, - integration: this.renderIntegration(props.integration) + integration: this.renderIntegration(props.integration), + methodResponses: this.renderMethodResponses(options.methodResponses), }; const resource = new CfnMethod(this, 'Resource', methodProps); @@ -188,6 +194,34 @@ export class Method extends cdk.Construct { credentials, }; } + + private renderMethodResponses(methodResponses: MethodResponse[] | undefined): CfnMethod.MethodResponseProperty[] | undefined { + if (!methodResponses) { + // Fall back to nothing + return undefined; + } + + return methodResponses.map(mr => { + let responseModels: {[contentType: string]: string} | undefined; + + if (mr.responseModels) { + responseModels = {}; + for (const contentType in mr.responseModels) { + if (mr.responseModels.hasOwnProperty(contentType)) { + responseModels[contentType] = mr.responseModels[contentType].modelId; + } + } + } + + const methodResponseProp = { + statusCode: mr.statusCode, + responseParameters: mr.responseParameters, + responseModels, + }; + + return methodResponseProp; + }); + } } export enum AuthorizationType { diff --git a/packages/@aws-cdk/aws-apigateway/lib/methodresponse.ts b/packages/@aws-cdk/aws-apigateway/lib/methodresponse.ts new file mode 100644 index 0000000000000..0307ec610486a --- /dev/null +++ b/packages/@aws-cdk/aws-apigateway/lib/methodresponse.ts @@ -0,0 +1,25 @@ +import { IModel } from './model'; + +export interface MethodResponse { + + /** + * The method response's status code, which you map to an IntegrationResponse. + */ + statusCode: string; + + /** + * Response parameters that API Gateway sends to the client that called a method. + * Specify response parameters as key-value pairs (string-to-Boolean maps), with + * a destination as the key and a Boolean as the value. Specify the destination + * using the following pattern: method.response.header.name, where the name is a + * valid, unique header name. The Boolean specifies whether a parameter is required. + */ + responseParameters?: { [destination: string]: boolean }; + + /** + * The resources used for the response's content type. Specify response models as + * key-value pairs (string-to-string maps), with a content type as the key and a Model + * resource name as the value. + */ + responseModels?: { [contentType: string]: IModel }; +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-apigateway/lib/model.ts b/packages/@aws-cdk/aws-apigateway/lib/model.ts new file mode 100644 index 0000000000000..61bdc43877494 --- /dev/null +++ b/packages/@aws-cdk/aws-apigateway/lib/model.ts @@ -0,0 +1,13 @@ +export interface IModel { + readonly modelId: string; +} + +export class EmptyModel implements IModel { + public readonly modelId = 'Empty'; +} + +export class ErrorModel implements IModel { + public readonly modelId = 'Error'; +} + +// TODO: Implement Model, enabling management of custom models. \ No newline at end of file diff --git a/packages/@aws-cdk/aws-apigateway/test/test.method.ts b/packages/@aws-cdk/aws-apigateway/test/test.method.ts index 645d1f9f9f398..3a45f3d73cfe0 100644 --- a/packages/@aws-cdk/aws-apigateway/test/test.method.ts +++ b/packages/@aws-cdk/aws-apigateway/test/test.method.ts @@ -5,7 +5,7 @@ import iam = require('@aws-cdk/aws-iam'); import cdk = require('@aws-cdk/cdk'); import { Test } from 'nodeunit'; import apigateway = require('../lib'); -import { ConnectionType } from '../lib'; +import { ConnectionType, EmptyModel, ErrorModel } from '../lib'; export = { 'default setup'(test: Test) { @@ -301,6 +301,63 @@ export = { // THEN test.throws(() => api.root.addMethod('GET', integration), /cannot set 'vpcLink' where 'connectionType' is INTERNET/); + test.done(); + }, + + 'methodResponse set one or more method responses via options'(test: Test) { + // GIVEN + const stack = new cdk.Stack(); + const api = new apigateway.RestApi(stack, 'test-api', { deploy: false }); + + // WHEN + new apigateway.Method(stack, 'method-man', { + httpMethod: 'GET', + resource: api.root, + options: { + methodResponses: [{ + statusCode: '200' + }, { + statusCode: "400", + responseParameters: { + 'method.response.header.killerbees': false + } + }, { + statusCode: "500", + responseParameters: { + 'method.response.header.errthing': true + }, + responseModels: { + 'application/json': new EmptyModel(), + 'text/plain': new ErrorModel() + } + } + ] + } + }); + + // THEN + expect(stack).to(haveResource('AWS::ApiGateway::Method', { + HttpMethod: 'GET', + MethodResponses: [{ + StatusCode: "200" + }, { + StatusCode: "400", + ResponseParameters: { + 'method.response.header.killerbees': false + } + }, { + StatusCode: "500", + ResponseParameters: { + 'method.response.header.errthing': true + }, + ResponseModels: { + 'application/json': 'Empty', + 'text/plain': 'Error' + } + } + ] + })); + test.done(); } };