Aws-cdk: Make AppSync and MappingTemplate L2-constructs work with CodePipeline deployments

Created on 18 May 2020  路  8Comments  路  Source: aws/aws-cdk


Deploy an AppSync API with a schema definition file and resolver mapping templates in a CodePipeline using CloudFormation actions.

Use Case


I want to deploy an AppSync API in a CodePipeline and I don't want to inline the schema into the CDK code because I want to generate model classes from it.

Currently, the schema definition must be provided either as a string or as an asset (not yet supported by CloudFormations actions).
It is not possible to provide S3-locations without redefining the current L2-construct.

CDK source code:

https://github.com/aws/aws-cdk/blob/bf0113b01bb1c5548d87391b01670fca12636609/packages/%40aws-cdk/aws-appsync/lib/graphqlapi.ts#L236-L243

Proposed Solution


Provide S3-locations of the schema definition file and any resolver mapping templates to the synthesized template using CloudFormation parameters, similar to CfnParametersCode (see example here).

Since the number of mapping templates can be very high, a solution that requires only one parameter representing the S3-folder containing the mapping templates would be useful.

Creating an AppSync API and mapping templates could look like:

const schema = new cdk.CfnParameter(this, 'GraphQLSchemaS3Location');
const resolversDir = new cdk.CfnParameter(this, 'GraphQLMappingTemplatesS3Location');

const api = new appsync.GraphQLApi(this, 'GraphQLApi', {
  name: `GraphQLApi`,
  schemaDefinitionLocation: schema,
});

someDataSource.createQueryResolver({
  field: 'getHello',
  requestTemplate:  appsync.MappingTemplate.fromS3Location(resolversDir, 'getHello-request-mapping-template.vtl'),
  responseTemplate: appsync.MappingTemplate.fromS3Location(resolversDir, 'getHello-response-mapping-template.vtl'),
});

Other

Related question on Gitter.

  • [ ] :wave: I may be able to implement this feature request
  • [ ] :warning: This feature might incur a breaking change

This is a :rocket: Feature Request

@aws-cdaws-appsync @aws-cdaws-codepipeline efformedium feature-request p2

All 8 comments

Is this covered by aws/aws-cdk-rfcs#49?

I can't deploy using CI/CD at the moment because of missing assets support 馃槥

It looks like CloudFormations already has support for using s3 locations: resolver docs and schema docs.

Seems like the most minimal solution would be to offer a prop for GraphQLApi that takes a S3 location and to open up props in resolver for requestMappingTemplateS3Location and responseMappingTemplateS3Location.

Both would be all would be strings as that's what the CloudFormation props take...

@asterikx what do you think? I know this was a little different with the proposed solution.

@BryanPan342 Thanks for you response.

Both would be all would be strings as that's what the CloudFormation props take...

I don't completely understand. Could you maybe sketch your solution? My idea was that the CDK would take care of uploading the referenced schema/resolver files to S3 and use the corresponding S3 locations (strings) as input parameters to the synthesized CFN template during deployment. Very similar to how lambda.CfnParametersCode, see this example.

Since pipelines.CdkPipeline now supports Assets, I think sth. like the following would best cover all use cases (cdk deploy and pipeline deployments using pipelines.CdkPipeline)

const api = new appsync.GraphQLApi(this, 'GraphQLApi', {
  name: `GraphQLApi`,
  schemaDefinition: appsync.SchemaDefinition.fromAsset('./schema.graphql'),
});

someDataSource.createQueryResolver({
  field: 'getHello',
  requestTemplate:  appsync.MappingTemplate.fromAsset('./resolvers/getHello-request-mapping-template.vtl'),
  responseTemplate: appsync.MappingTemplate.fromAsset('./resolvers/getHello-response-mapping-template.vtl'),
});

@asterikx

Ah I see. The feature you are suggesting is for CDK to upload assets with AppSync and route the S3 location into the CloudFormation definition.

I'm going to investigate this further, but what's the issue of using something like this for schema:

const api = new appsync.GraphQLApi(this, 'GraphQLApi', {
  name: `GraphQLApi`,
  schemaDefinitionFile: path.join(__dirname, 'schema.graphql'),
});

Ah I see. The feature you are suggesting is for CDK to upload assets with AppSync and route the S3 location into the CloudFormation definition.

Yes.

I'm going to investigate this further, but what's the issue of using something like this for schema

True, this was a conceptual misunderstanding from my side. Indeed schemaDefinitionFile will simply inline the schema during synthesis.

https://github.com/aws/aws-cdk/blob/9867555cbde59b6d7c51c302ac7ee8bf2a603f36/packages/%40aws-cdk/aws-appsync/lib/graphqlapi.ts#L357-L363

I thought schemaDefinitionFile would use Assets under the hood, which is not supported by codepipeline.Pipeline (see this issue for example).

Also, pipelines.CdkPipeline now supports asset publishing to S3. So it would be useful to support S3 locations in AppSync. In this way, the size of the synthesized CFN templates could also be reduced, as the inlined schema definition and the resolver templates are significantly larger (depending on the application) than the corresponding references to S3. One problem I see is that the number of assets explodes as the API grows, as we need to two assets per operation (request and response mapping templates). Not quite sure if that scales with the current asset publishing implementation (see here and here). What do you think @BryanPan342 @skinny85?

One problem I see is that the number of assets explodes as the API grows, as we need to two assets per operation (request and response mapping templates)

@asterikx this is a really good point that we have also talked about. For now, we thought that it would be okay not to have s3 asset publishing because we haven't gotten an issue raised about size yet. And even if schema.graphql was large, a workaround would be to segment your GraphQL API across multiple APIs.

I dont quite understand this part.

One problem I see is that the number of assets explodes as the API grows, as we need to two assets per operation (request and response mapping templates)

I'm not an expert on cdkPipeline but if im not mistaken, the mapping templates aren't techinically assets because they are attributes to a AWS::AppSync::Resolver.

One problem I see is that the number of assets explodes as the API grows, as we need to two assets per operation (request and response mapping templates)

With the current implementation, there are no assets. Sorry for the confusion, I was hypothesizing here. If we were to support RequestMappingTemplateS3Location and ResponseMappingTemplateS3Location through assets, the number of required assets for an AppSync API would grow linearly with the number of resolvers, i.e. the number of operations.

I'm fine with closing this for now. There might be more critical issues at this time.

Ah I see. I think this discussion would be great to keep open.

I think if we could change the issue name/message to reflect our discussion that would be fantastic!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

eladb picture eladb  路  3Comments

pepastach picture pepastach  路  3Comments

artyom-melnikov picture artyom-melnikov  路  3Comments

nzspambot picture nzspambot  路  3Comments

EduardTheThird picture EduardTheThird  路  3Comments