From 275351a48be7bb49b9959fc7ccda4d2d4642f3c2 Mon Sep 17 00:00:00 2001 From: Kyle Villegas <86266231+kylevillegas93@users.noreply.github.com> Date: Mon, 6 Dec 2021 14:26:16 -0700 Subject: [PATCH] fix(appsync): add caching config to AppSync resolvers (#17815) While trying to add caching config to some of my application's resolvers, I discovered that the BaseResolverProps do not include caching configuration like the CfnResolver does. This PR adds this missing caching configuration to the BaseResolverProps and adds the configuration as part of the creation of the CfnResolver. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../aws-appsync/lib/caching-config.ts | 22 ++++ .../@aws-cdk/aws-appsync/lib/caching-key.ts | 4 + packages/@aws-cdk/aws-appsync/lib/index.ts | 2 + packages/@aws-cdk/aws-appsync/lib/resolver.ts | 25 +++- .../test/appsync-caching-config.test.ts | 109 ++++++++++++++++++ .../test/integ.api-import.expected.json | 3 + .../test/integ.appsync-lambda.expected.json | 4 + .../test/integ.auth-apikey.expected.json | 2 + .../integ.graphql-elasticsearch.expected.json | 1 + .../test/integ.graphql-iam.expected.json | 3 + .../test/integ.graphql-schema.expected.json | 2 + .../test/integ.graphql.expected.json | 24 ++++ 12 files changed, 200 insertions(+), 1 deletion(-) create mode 100644 packages/@aws-cdk/aws-appsync/lib/caching-config.ts create mode 100644 packages/@aws-cdk/aws-appsync/lib/caching-key.ts create mode 100644 packages/@aws-cdk/aws-appsync/test/appsync-caching-config.test.ts diff --git a/packages/@aws-cdk/aws-appsync/lib/caching-config.ts b/packages/@aws-cdk/aws-appsync/lib/caching-config.ts new file mode 100644 index 0000000000000..bd189e41ee321 --- /dev/null +++ b/packages/@aws-cdk/aws-appsync/lib/caching-config.ts @@ -0,0 +1,22 @@ +import { Duration } from '@aws-cdk/core'; + +/** + * CachingConfig for AppSync resolvers + */ +export interface CachingConfig { + /** + * The caching keys for a resolver that has caching enabled. + * Valid values are entries from the $context.arguments, $context.source, and $context.identity maps. + * + * @default - No caching keys + */ + readonly cachingKeys?: string[]; + + /** + * The TTL in seconds for a resolver that has caching enabled. + * Valid values are between 1 and 3600 seconds. + * + * @default - No TTL + */ + readonly ttl?: Duration; +} diff --git a/packages/@aws-cdk/aws-appsync/lib/caching-key.ts b/packages/@aws-cdk/aws-appsync/lib/caching-key.ts new file mode 100644 index 0000000000000..a20f9e636b676 --- /dev/null +++ b/packages/@aws-cdk/aws-appsync/lib/caching-key.ts @@ -0,0 +1,4 @@ +export const CONTEXT_ARGUMENTS_CACHING_KEY = '$context.arguments'; +export const CONTEXT_SOURCE_CACHING_KEY = '$context.source'; +export const CONTEXT_IDENTITY_CACHING_KEY = '$context.identity'; +export const BASE_CACHING_KEYS = [CONTEXT_ARGUMENTS_CACHING_KEY, CONTEXT_SOURCE_CACHING_KEY, CONTEXT_IDENTITY_CACHING_KEY]; diff --git a/packages/@aws-cdk/aws-appsync/lib/index.ts b/packages/@aws-cdk/aws-appsync/lib/index.ts index 5b0f12cf75844..a102b16ac37a1 100644 --- a/packages/@aws-cdk/aws-appsync/lib/index.ts +++ b/packages/@aws-cdk/aws-appsync/lib/index.ts @@ -1,6 +1,8 @@ // AWS::AppSync CloudFormation Resources: export * from './appsync-function'; export * from './appsync.generated'; +export * from './caching-config'; +export * from './caching-key'; export * from './key'; export * from './data-source'; export * from './mapping-template'; diff --git a/packages/@aws-cdk/aws-appsync/lib/resolver.ts b/packages/@aws-cdk/aws-appsync/lib/resolver.ts index eb65a59f494fd..ea2a4a99d900a 100644 --- a/packages/@aws-cdk/aws-appsync/lib/resolver.ts +++ b/packages/@aws-cdk/aws-appsync/lib/resolver.ts @@ -1,13 +1,15 @@ import { Construct } from 'constructs'; import { IAppsyncFunction } from './appsync-function'; import { CfnResolver } from './appsync.generated'; +import { CachingConfig } from './caching-config'; +import { BASE_CACHING_KEYS } from './caching-key'; import { BaseDataSource } from './data-source'; import { IGraphqlApi } from './graphqlapi-base'; import { MappingTemplate } from './mapping-template'; // v2 - keep this import as a separate section to reduce merge conflict when forward merging with the v2 branch. // eslint-disable-next-line -import { Construct as CoreConstruct } from '@aws-cdk/core'; +import { Construct as CoreConstruct, Token } from '@aws-cdk/core'; /** * Basic properties for an AppSync resolver @@ -40,6 +42,12 @@ export interface BaseResolverProps { * @default - No mapping template */ readonly responseMappingTemplate?: MappingTemplate; + /** + * The caching configuration for this resolver + * + * @default - No caching configuration + */ + readonly cachingConfig?: CachingConfig; } /** @@ -86,6 +94,17 @@ export class Resolver extends CoreConstruct { throw new Error(`Pipeline Resolver cannot have data source. Received: ${props.dataSource.name}`); } + if (props.cachingConfig?.ttl && (props.cachingConfig.ttl.toSeconds() < 1 || props.cachingConfig.ttl.toSeconds() > 3600)) { + throw new Error(`Caching config TTL must be between 1 and 3600 seconds. Received: ${props.cachingConfig.ttl.toSeconds()}`); + } + + if (props.cachingConfig?.cachingKeys) { + if (props.cachingConfig.cachingKeys.find(cachingKey => + !Token.isUnresolved(cachingKey) && !BASE_CACHING_KEYS.find(baseCachingKey => cachingKey.startsWith(baseCachingKey)))) { + throw new Error(`Caching config keys must begin with $context.arguments, $context.source or $context.identity. Received: ${props.cachingConfig.cachingKeys}`); + } + } + this.resolver = new CfnResolver(this, 'Resource', { apiId: props.api.apiId, typeName: props.typeName, @@ -95,6 +114,10 @@ export class Resolver extends CoreConstruct { pipelineConfig: pipelineConfig, requestMappingTemplate: props.requestMappingTemplate ? props.requestMappingTemplate.renderTemplate() : undefined, responseMappingTemplate: props.responseMappingTemplate ? props.responseMappingTemplate.renderTemplate() : undefined, + cachingConfig: { + cachingKeys: props.cachingConfig?.cachingKeys, + ttl: props.cachingConfig?.ttl?.toSeconds(), + }, }); props.api.addSchemaDependency(this.resolver); if (props.dataSource) { diff --git a/packages/@aws-cdk/aws-appsync/test/appsync-caching-config.test.ts b/packages/@aws-cdk/aws-appsync/test/appsync-caching-config.test.ts new file mode 100644 index 0000000000000..716dfb9d1bba6 --- /dev/null +++ b/packages/@aws-cdk/aws-appsync/test/appsync-caching-config.test.ts @@ -0,0 +1,109 @@ +import * as path from 'path'; +import { Template } from '@aws-cdk/assertions'; +import * as lambda from '@aws-cdk/aws-lambda'; +import * as cdk from '@aws-cdk/core'; +import { Duration } from '@aws-cdk/core'; +import * as appsync from '../lib'; + +let stack: cdk.Stack; +let api: appsync.GraphqlApi; + +beforeEach(() => { + // GIVEN + stack = new cdk.Stack(); + api = new appsync.GraphqlApi(stack, 'api', { + name: 'api', + schema: appsync.Schema.fromAsset(path.join(__dirname, 'appsync.lambda.graphql')), + }); +}); + +describe('Lambda caching config', () => { + // GIVEN + let func: lambda.Function; + + beforeEach(() => { + func = new lambda.Function(stack, 'func', { + code: lambda.Code.fromAsset(path.join(__dirname, 'verify/lambda-tutorial')), + handler: 'lambda-tutorial.handler', + runtime: lambda.Runtime.NODEJS_12_X, + }); + }); + + test('Lambda resolver contains caching config with caching key and TTL', () => { + // WHEN + const lambdaDS = api.addLambdaDataSource('LambdaDS', func); + + lambdaDS.createResolver({ + typeName: 'Query', + fieldName: 'allPosts', + cachingConfig: { + cachingKeys: ['$context.arguments', '$context.source', '$context.identity'], + ttl: Duration.seconds(300), + }, + }); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::Resolver', { + TypeName: 'Query', + FieldName: 'allPosts', + CachingConfig: { + CachingKeys: ['$context.arguments', '$context.source', '$context.identity'], + Ttl: 300, + }, + }); + }); + + test('Lambda resolver throws error when caching config with TTL is less than 1 second', () => { + // WHEN + const ttlInSconds = 0; + const lambdaDS = api.addLambdaDataSource('LambdaDS', func); + + // THEN + expect(() => { + lambdaDS.createResolver({ + typeName: 'Query', + fieldName: 'allPosts', + cachingConfig: { + cachingKeys: ['$context.identity'], + ttl: Duration.seconds(0), + }, + }); + }).toThrowError(`Caching config TTL must be between 1 and 3600 seconds. Received: ${ttlInSconds}`); + }); + + test('Lambda resolver throws error when caching config with TTL is greater than 3600 seconds', () => { + // WHEN + const ttlInSconds = 4200; + const lambdaDS = api.addLambdaDataSource('LambdaDS', func); + + // THEN + expect(() => { + lambdaDS.createResolver({ + typeName: 'Query', + fieldName: 'allPosts', + cachingConfig: { + cachingKeys: ['$context.identity'], + ttl: Duration.seconds(ttlInSconds), + }, + }); + }).toThrowError(`Caching config TTL must be between 1 and 3600 seconds. Received: ${ttlInSconds}`); + }); + + test('Lambda resolver throws error when caching config has invalid caching keys', () => { + // WHEN + const invalidCachingKeys = ['$context.metadata']; + const lambdaDS = api.addLambdaDataSource('LambdaDS', func); + + // THEN + expect(() => { + lambdaDS.createResolver({ + typeName: 'Query', + fieldName: 'allPosts', + cachingConfig: { + cachingKeys: invalidCachingKeys, + ttl: Duration.seconds(300), + }, + }); + }).toThrowError(`Caching config keys must begin with $context.arguments, $context.source or $context.identity. Received: ${invalidCachingKeys}`); + }); +}); diff --git a/packages/@aws-cdk/aws-appsync/test/integ.api-import.expected.json b/packages/@aws-cdk/aws-appsync/test/integ.api-import.expected.json index e4b54f04116fc..844eca96cfb86 100644 --- a/packages/@aws-cdk/aws-appsync/test/integ.api-import.expected.json +++ b/packages/@aws-cdk/aws-appsync/test/integ.api-import.expected.json @@ -143,6 +143,7 @@ }, "FieldName": "getTests", "TypeName": "Query", + "CachingConfig": {}, "DataSourceName": "ds", "Kind": "UNIT", "RequestMappingTemplate": "{\"version\" : \"2017-02-28\", \"operation\" : \"Scan\"}", @@ -160,6 +161,7 @@ }, "FieldName": "addTest", "TypeName": "Mutation", + "CachingConfig": {}, "DataSourceName": "ds", "Kind": "UNIT", "RequestMappingTemplate": "\n #set($input = $ctx.args.test)\n \n {\n \"version\": \"2017-02-28\",\n \"operation\": \"PutItem\",\n \"key\" : {\n \"id\" : $util.dynamodb.toDynamoDBJson($util.autoId())\n },\n \"attributeValues\": $util.dynamodb.toMapValuesJson($input)\n }", @@ -223,6 +225,7 @@ }, "FieldName": "version", "TypeName": "test", + "CachingConfig": {}, "Kind": "PIPELINE", "PipelineConfig": { "Functions": [ diff --git a/packages/@aws-cdk/aws-appsync/test/integ.appsync-lambda.expected.json b/packages/@aws-cdk/aws-appsync/test/integ.appsync-lambda.expected.json index f4bd20a97d90e..157cde0ccdced 100644 --- a/packages/@aws-cdk/aws-appsync/test/integ.appsync-lambda.expected.json +++ b/packages/@aws-cdk/aws-appsync/test/integ.appsync-lambda.expected.json @@ -114,6 +114,7 @@ }, "FieldName": "getPost", "TypeName": "Query", + "CachingConfig": {}, "DataSourceName": "LambdaDS", "Kind": "UNIT", "RequestMappingTemplate": "{\"version\": \"2017-02-28\", \"operation\": \"Invoke\", \"payload\": { \"field\": \"getPost\", \"arguments\": $utils.toJson($context.arguments)}}", @@ -135,6 +136,7 @@ }, "FieldName": "allPosts", "TypeName": "Query", + "CachingConfig": {}, "DataSourceName": "LambdaDS", "Kind": "UNIT", "RequestMappingTemplate": "{\"version\": \"2017-02-28\", \"operation\": \"Invoke\", \"payload\": { \"field\": \"allPosts\"}}", @@ -156,6 +158,7 @@ }, "FieldName": "addPost", "TypeName": "Mutation", + "CachingConfig": {}, "DataSourceName": "LambdaDS", "Kind": "UNIT", "RequestMappingTemplate": "{\"version\": \"2017-02-28\", \"operation\": \"Invoke\", \"payload\": { \"field\": \"addPost\", \"arguments\": $utils.toJson($context.arguments)}}", @@ -177,6 +180,7 @@ }, "FieldName": "relatedPosts", "TypeName": "Post", + "CachingConfig": {}, "DataSourceName": "LambdaDS", "Kind": "UNIT", "RequestMappingTemplate": "{\"version\": \"2017-02-28\", \"operation\": \"BatchInvoke\", \"payload\": { \"field\": \"relatedPosts\", \"source\": $utils.toJson($context.source)}}", diff --git a/packages/@aws-cdk/aws-appsync/test/integ.auth-apikey.expected.json b/packages/@aws-cdk/aws-appsync/test/integ.auth-apikey.expected.json index ed0307de0e72f..68ec8c15d8ad3 100644 --- a/packages/@aws-cdk/aws-appsync/test/integ.auth-apikey.expected.json +++ b/packages/@aws-cdk/aws-appsync/test/integ.auth-apikey.expected.json @@ -132,6 +132,7 @@ }, "FieldName": "getTests", "TypeName": "Query", + "CachingConfig": {}, "DataSourceName": "testDataSource", "Kind": "UNIT", "RequestMappingTemplate": "{\"version\" : \"2017-02-28\", \"operation\" : \"Scan\"}", @@ -153,6 +154,7 @@ }, "FieldName": "addTest", "TypeName": "Mutation", + "CachingConfig": {}, "DataSourceName": "testDataSource", "Kind": "UNIT", "RequestMappingTemplate": "\n #set($input = $ctx.args.test)\n \n {\n \"version\": \"2017-02-28\",\n \"operation\": \"PutItem\",\n \"key\" : {\n \"id\" : $util.dynamodb.toDynamoDBJson($util.autoId())\n },\n \"attributeValues\": $util.dynamodb.toMapValuesJson($input)\n }", diff --git a/packages/@aws-cdk/aws-appsync/test/integ.graphql-elasticsearch.expected.json b/packages/@aws-cdk/aws-appsync/test/integ.graphql-elasticsearch.expected.json index 22e64957700e9..c0a78de80a219 100644 --- a/packages/@aws-cdk/aws-appsync/test/integ.graphql-elasticsearch.expected.json +++ b/packages/@aws-cdk/aws-appsync/test/integ.graphql-elasticsearch.expected.json @@ -196,6 +196,7 @@ }, "FieldName": "getTests", "TypeName": "Query", + "CachingConfig": {}, "DataSourceName": "ds", "Kind": "UNIT", "RequestMappingTemplate": "{\"version\":\"2017-02-28\",\"operation\":\"GET\",\"path\":\"/id/post/_search\",\"params\":{\"headers\":{},\"queryString\":{},\"body\":{\"from\":0,\"size\":50}}}", diff --git a/packages/@aws-cdk/aws-appsync/test/integ.graphql-iam.expected.json b/packages/@aws-cdk/aws-appsync/test/integ.graphql-iam.expected.json index 374a89dc33d14..268ca24ae7d13 100644 --- a/packages/@aws-cdk/aws-appsync/test/integ.graphql-iam.expected.json +++ b/packages/@aws-cdk/aws-appsync/test/integ.graphql-iam.expected.json @@ -163,6 +163,7 @@ }, "FieldName": "getTest", "TypeName": "Query", + "CachingConfig": {}, "DataSourceName": "testDataSource", "Kind": "UNIT", "RequestMappingTemplate": "{\"version\": \"2017-02-28\", \"operation\": \"GetItem\", \"key\": {\"id\": $util.dynamodb.toDynamoDBJson($ctx.args.id)}}", @@ -184,6 +185,7 @@ }, "FieldName": "getTests", "TypeName": "Query", + "CachingConfig": {}, "DataSourceName": "testDataSource", "Kind": "UNIT", "RequestMappingTemplate": "{\"version\" : \"2017-02-28\", \"operation\" : \"Scan\"}", @@ -205,6 +207,7 @@ }, "FieldName": "addTest", "TypeName": "Mutation", + "CachingConfig": {}, "DataSourceName": "testDataSource", "Kind": "UNIT", "RequestMappingTemplate": "\n #set($input = $ctx.args.test)\n \n {\n \"version\": \"2017-02-28\",\n \"operation\": \"PutItem\",\n \"key\" : {\n \"id\" : $util.dynamodb.toDynamoDBJson($util.autoId())\n },\n \"attributeValues\": $util.dynamodb.toMapValuesJson($input)\n }", diff --git a/packages/@aws-cdk/aws-appsync/test/integ.graphql-schema.expected.json b/packages/@aws-cdk/aws-appsync/test/integ.graphql-schema.expected.json index a6e5ff5764331..9cccc3b45ef44 100644 --- a/packages/@aws-cdk/aws-appsync/test/integ.graphql-schema.expected.json +++ b/packages/@aws-cdk/aws-appsync/test/integ.graphql-schema.expected.json @@ -131,6 +131,7 @@ }, "FieldName": "getPlanets", "TypeName": "Query", + "CachingConfig": {}, "DataSourceName": "planets", "Kind": "UNIT", "RequestMappingTemplate": "{\"version\" : \"2017-02-28\", \"operation\" : \"Scan\"}", @@ -152,6 +153,7 @@ }, "FieldName": "addPlanet", "TypeName": "Mutation", + "CachingConfig": {}, "DataSourceName": "planets", "Kind": "UNIT", "RequestMappingTemplate": "\n #set($input = $context.arguments)\n $util.qr($input.put(\"name\", $context.arguments.name))\n$util.qr($input.put(\"diameter\", $context.arguments.diameter))\n$util.qr($input.put(\"rotationPeriod\", $context.arguments.rotationPeriod))\n$util.qr($input.put(\"orbitalPeriod\", $context.arguments.orbitalPeriod))\n$util.qr($input.put(\"gravityPeriod\", $context.arguments.gravity))\n$util.qr($input.put(\"population\", $context.arguments.population))\n$util.qr($input.put(\"climates\", $context.arguments.climates))\n$util.qr($input.put(\"terrains\", $context.arguments.terrains))\n$util.qr($input.put(\"surfaceWater\", $context.arguments.surfaceWater))\n {\n \"version\": \"2017-02-28\",\n \"operation\": \"PutItem\",\n \"key\" : {\n \"id\" : $util.dynamodb.toDynamoDBJson($util.autoId())\n },\n \"attributeValues\": $util.dynamodb.toMapValuesJson($input)\n }", diff --git a/packages/@aws-cdk/aws-appsync/test/integ.graphql.expected.json b/packages/@aws-cdk/aws-appsync/test/integ.graphql.expected.json index 6f9fd9c12d899..a6acba469e336 100644 --- a/packages/@aws-cdk/aws-appsync/test/integ.graphql.expected.json +++ b/packages/@aws-cdk/aws-appsync/test/integ.graphql.expected.json @@ -103,6 +103,7 @@ }, "FieldName": "getServiceVersion", "TypeName": "Query", + "CachingConfig": {}, "DataSourceName": "None", "Kind": "UNIT", "RequestMappingTemplate": "{\"version\":\"2017-02-28\"}", @@ -211,6 +212,7 @@ }, "FieldName": "getCustomers", "TypeName": "Query", + "CachingConfig": {}, "DataSourceName": "Customer", "Kind": "UNIT", "RequestMappingTemplate": "{\"version\" : \"2017-02-28\", \"operation\" : \"Scan\"}", @@ -232,6 +234,7 @@ }, "FieldName": "getCustomer", "TypeName": "Query", + "CachingConfig": {}, "DataSourceName": "Customer", "Kind": "UNIT", "RequestMappingTemplate": "{\"version\": \"2017-02-28\", \"operation\": \"GetItem\", \"key\": {\"id\": $util.dynamodb.toDynamoDBJson($ctx.args.id)}}", @@ -253,6 +256,7 @@ }, "FieldName": "addCustomer", "TypeName": "Mutation", + "CachingConfig": {}, "DataSourceName": "Customer", "Kind": "UNIT", "RequestMappingTemplate": "\n #set($input = $ctx.args.customer)\n \n {\n \"version\": \"2017-02-28\",\n \"operation\": \"PutItem\",\n \"key\" : {\n \"id\" : $util.dynamodb.toDynamoDBJson($util.autoId())\n },\n \"attributeValues\": $util.dynamodb.toMapValuesJson($input)\n }", @@ -274,6 +278,7 @@ }, "FieldName": "saveCustomer", "TypeName": "Mutation", + "CachingConfig": {}, "DataSourceName": "Customer", "Kind": "UNIT", "RequestMappingTemplate": "\n #set($input = $ctx.args.customer)\n \n {\n \"version\": \"2017-02-28\",\n \"operation\": \"PutItem\",\n \"key\" : {\n \"id\" : $util.dynamodb.toDynamoDBJson($ctx.args.id)\n },\n \"attributeValues\": $util.dynamodb.toMapValuesJson($input)\n }", @@ -295,6 +300,7 @@ }, "FieldName": "saveCustomerWithFirstOrder", "TypeName": "Mutation", + "CachingConfig": {}, "DataSourceName": "Customer", "Kind": "UNIT", "RequestMappingTemplate": "\n #set($input = $ctx.args.order)\n $util.qr($input.put(\"referral\", referral))\n {\n \"version\": \"2017-02-28\",\n \"operation\": \"PutItem\",\n \"key\" : {\n \"order\" : $util.dynamodb.toDynamoDBJson($util.autoId()),\"customer\" : $util.dynamodb.toDynamoDBJson($ctx.args.customer.id)\n },\n \"attributeValues\": $util.dynamodb.toMapValuesJson($input)\n }", @@ -316,6 +322,7 @@ }, "FieldName": "removeCustomer", "TypeName": "Mutation", + "CachingConfig": {}, "DataSourceName": "Customer", "Kind": "UNIT", "RequestMappingTemplate": "{\"version\": \"2017-02-28\", \"operation\": \"DeleteItem\", \"key\": {\"id\": $util.dynamodb.toDynamoDBJson($ctx.args.id)}}", @@ -435,6 +442,7 @@ }, "FieldName": "getCustomerOrdersEq", "TypeName": "Query", + "CachingConfig": {}, "DataSourceName": "Order", "Kind": "UNIT", "RequestMappingTemplate": "{\"version\" : \"2017-02-28\", \"operation\" : \"Query\", \"query\" : {\n \"expression\" : \"#customer = :customer\",\n \"expressionNames\" : {\n \"#customer\" : \"customer\"\n },\n \"expressionValues\" : {\n \":customer\" : $util.dynamodb.toDynamoDBJson($ctx.args.customer)\n }\n }}", @@ -456,6 +464,7 @@ }, "FieldName": "getOrderCustomersEq", "TypeName": "Query", + "CachingConfig": {}, "DataSourceName": "Order", "Kind": "UNIT", "RequestMappingTemplate": "{\"version\" : \"2017-02-28\", \"operation\" : \"Query\", \"index\" : \"orderIndex\", \"query\" : {\n \"expression\" : \"#order = :order\",\n \"expressionNames\" : {\n \"#order\" : \"order\"\n },\n \"expressionValues\" : {\n \":order\" : $util.dynamodb.toDynamoDBJson($ctx.args.order)\n }\n }}", @@ -477,6 +486,7 @@ }, "FieldName": "getCustomerOrdersLt", "TypeName": "Query", + "CachingConfig": {}, "DataSourceName": "Order", "Kind": "UNIT", "RequestMappingTemplate": "{\"version\" : \"2017-02-28\", \"operation\" : \"Query\", \"query\" : {\n \"expression\" : \"#customer < :customer\",\n \"expressionNames\" : {\n \"#customer\" : \"customer\"\n },\n \"expressionValues\" : {\n \":customer\" : $util.dynamodb.toDynamoDBJson($ctx.args.customer)\n }\n }}", @@ -498,6 +508,7 @@ }, "FieldName": "getOrderCustomersLt", "TypeName": "Query", + "CachingConfig": {}, "DataSourceName": "Order", "Kind": "UNIT", "RequestMappingTemplate": "{\"version\" : \"2017-02-28\", \"operation\" : \"Query\", \"index\" : \"orderIndex\", \"query\" : {\n \"expression\" : \"#order < :order\",\n \"expressionNames\" : {\n \"#order\" : \"order\"\n },\n \"expressionValues\" : {\n \":order\" : $util.dynamodb.toDynamoDBJson($ctx.args.order)\n }\n }}", @@ -519,6 +530,7 @@ }, "FieldName": "getCustomerOrdersLe", "TypeName": "Query", + "CachingConfig": {}, "DataSourceName": "Order", "Kind": "UNIT", "RequestMappingTemplate": "{\"version\" : \"2017-02-28\", \"operation\" : \"Query\", \"query\" : {\n \"expression\" : \"#customer <= :customer\",\n \"expressionNames\" : {\n \"#customer\" : \"customer\"\n },\n \"expressionValues\" : {\n \":customer\" : $util.dynamodb.toDynamoDBJson($ctx.args.customer)\n }\n }}", @@ -540,6 +552,7 @@ }, "FieldName": "getOrderCustomersLe", "TypeName": "Query", + "CachingConfig": {}, "DataSourceName": "Order", "Kind": "UNIT", "RequestMappingTemplate": "{\"version\" : \"2017-02-28\", \"operation\" : \"Query\", \"index\" : \"orderIndex\", \"query\" : {\n \"expression\" : \"#order <= :order\",\n \"expressionNames\" : {\n \"#order\" : \"order\"\n },\n \"expressionValues\" : {\n \":order\" : $util.dynamodb.toDynamoDBJson($ctx.args.order)\n }\n }}", @@ -561,6 +574,7 @@ }, "FieldName": "getCustomerOrdersGt", "TypeName": "Query", + "CachingConfig": {}, "DataSourceName": "Order", "Kind": "UNIT", "RequestMappingTemplate": "{\"version\" : \"2017-02-28\", \"operation\" : \"Query\", \"query\" : {\n \"expression\" : \"#customer > :customer\",\n \"expressionNames\" : {\n \"#customer\" : \"customer\"\n },\n \"expressionValues\" : {\n \":customer\" : $util.dynamodb.toDynamoDBJson($ctx.args.customer)\n }\n }}", @@ -582,6 +596,7 @@ }, "FieldName": "getOrderCustomersGt", "TypeName": "Query", + "CachingConfig": {}, "DataSourceName": "Order", "Kind": "UNIT", "RequestMappingTemplate": "{\"version\" : \"2017-02-28\", \"operation\" : \"Query\", \"index\" : \"orderIndex\", \"query\" : {\n \"expression\" : \"#order > :order\",\n \"expressionNames\" : {\n \"#order\" : \"order\"\n },\n \"expressionValues\" : {\n \":order\" : $util.dynamodb.toDynamoDBJson($ctx.args.order)\n }\n }}", @@ -603,6 +618,7 @@ }, "FieldName": "getCustomerOrdersGe", "TypeName": "Query", + "CachingConfig": {}, "DataSourceName": "Order", "Kind": "UNIT", "RequestMappingTemplate": "{\"version\" : \"2017-02-28\", \"operation\" : \"Query\", \"query\" : {\n \"expression\" : \"#customer >= :customer\",\n \"expressionNames\" : {\n \"#customer\" : \"customer\"\n },\n \"expressionValues\" : {\n \":customer\" : $util.dynamodb.toDynamoDBJson($ctx.args.customer)\n }\n }}", @@ -624,6 +640,7 @@ }, "FieldName": "getOrderCustomersGe", "TypeName": "Query", + "CachingConfig": {}, "DataSourceName": "Order", "Kind": "UNIT", "RequestMappingTemplate": "{\"version\" : \"2017-02-28\", \"operation\" : \"Query\", \"index\" : \"orderIndex\", \"query\" : {\n \"expression\" : \"#order >= :order\",\n \"expressionNames\" : {\n \"#order\" : \"order\"\n },\n \"expressionValues\" : {\n \":order\" : $util.dynamodb.toDynamoDBJson($ctx.args.order)\n }\n }}", @@ -645,6 +662,7 @@ }, "FieldName": "getCustomerOrdersFilter", "TypeName": "Query", + "CachingConfig": {}, "DataSourceName": "Order", "Kind": "UNIT", "RequestMappingTemplate": "{\"version\" : \"2017-02-28\", \"operation\" : \"Query\", \"query\" : {\n \"expression\" : \"#customer = :customer AND begins_with(#order, :order)\",\n \"expressionNames\" : {\n \"#customer\" : \"customer\", \"#order\" : \"order\"\n },\n \"expressionValues\" : {\n \":customer\" : $util.dynamodb.toDynamoDBJson($ctx.args.customer), \":order\" : $util.dynamodb.toDynamoDBJson($ctx.args.order)\n }\n }}", @@ -666,6 +684,7 @@ }, "FieldName": "getCustomerOrdersBetween", "TypeName": "Query", + "CachingConfig": {}, "DataSourceName": "Order", "Kind": "UNIT", "RequestMappingTemplate": "{\"version\" : \"2017-02-28\", \"operation\" : \"Query\", \"query\" : {\n \"expression\" : \"#customer = :customer AND #order BETWEEN :order1 AND :order2\",\n \"expressionNames\" : {\n \"#customer\" : \"customer\", \"#order\" : \"order\"\n },\n \"expressionValues\" : {\n \":customer\" : $util.dynamodb.toDynamoDBJson($ctx.args.customer), \":order1\" : $util.dynamodb.toDynamoDBJson($ctx.args.order1), \":order2\" : $util.dynamodb.toDynamoDBJson($ctx.args.order2)\n }\n }}", @@ -687,6 +706,7 @@ }, "FieldName": "getOrderCustomersFilter", "TypeName": "Query", + "CachingConfig": {}, "DataSourceName": "Order", "Kind": "UNIT", "RequestMappingTemplate": "{\"version\" : \"2017-02-28\", \"operation\" : \"Query\", \"query\" : {\n \"expression\" : \"#order = :order AND begins_with(#customer, :customer)\",\n \"expressionNames\" : {\n \"#order\" : \"order\", \"#customer\" : \"customer\"\n },\n \"expressionValues\" : {\n \":order\" : $util.dynamodb.toDynamoDBJson($ctx.args.order), \":customer\" : $util.dynamodb.toDynamoDBJson($ctx.args.customer)\n }\n }}", @@ -708,6 +728,7 @@ }, "FieldName": "getOrderCustomersBetween", "TypeName": "Query", + "CachingConfig": {}, "DataSourceName": "Order", "Kind": "UNIT", "RequestMappingTemplate": "{\"version\" : \"2017-02-28\", \"operation\" : \"Query\", \"index\" : \"orderIndex\", \"query\" : {\n \"expression\" : \"#order = :order AND #customer BETWEEN :customer1 AND :customer2\",\n \"expressionNames\" : {\n \"#order\" : \"order\", \"#customer\" : \"customer\"\n },\n \"expressionValues\" : {\n \":order\" : $util.dynamodb.toDynamoDBJson($ctx.args.order), \":customer1\" : $util.dynamodb.toDynamoDBJson($ctx.args.customer1), \":customer2\" : $util.dynamodb.toDynamoDBJson($ctx.args.customer2)\n }\n }}", @@ -828,6 +849,7 @@ }, "FieldName": "getPayment", "TypeName": "Query", + "CachingConfig": {}, "DataSourceName": "Payment", "Kind": "UNIT", "RequestMappingTemplate": "{\"version\": \"2017-02-28\", \"operation\": \"GetItem\", \"key\": {\"id\": $util.dynamodb.toDynamoDBJson($ctx.args.id)}}", @@ -849,6 +871,7 @@ }, "FieldName": "savePayment", "TypeName": "Mutation", + "CachingConfig": {}, "DataSourceName": "Payment", "Kind": "UNIT", "RequestMappingTemplate": "\n #set($input = $ctx.args.payment)\n \n {\n \"version\": \"2017-02-28\",\n \"operation\": \"PutItem\",\n \"key\" : {\n \"id\" : $util.dynamodb.toDynamoDBJson($util.autoId())\n },\n \"attributeValues\": $util.dynamodb.toMapValuesJson($input)\n }", @@ -909,6 +932,7 @@ }, "FieldName": "doPostOnAws", "TypeName": "Mutation", + "CachingConfig": {}, "DataSourceName": "http", "Kind": "UNIT", "RequestMappingTemplate": "{\n \"version\": \"2018-05-29\",\n \"method\": \"POST\",\n # if full path is https://api.xxxxxxxxx.com/posts then resourcePath would be /posts\n \"resourcePath\": \"/path/123\",\n \"params\":{\n \"body\": $util.toJson($ctx.args),\n \"headers\":{\n \"Content-Type\": \"application/json\",\n \"Authorization\": \"$ctx.request.headers.Authorization\"\n }\n }\n }",