diff --git a/doc/resolvers.md b/doc/resolvers.md index bc9d20a7..2c56782f 100644 --- a/doc/resolvers.md +++ b/doc/resolvers.md @@ -33,11 +33,15 @@ appSync: - `caching`: [See below](#Caching) - `sync`: [See SyncConfig](syncConfig.md) -## JavaScript vs VTL +## JavaScript, VTL, or Direct Lambda -When `code` is specified, the JavaScript runtime is used. When `request` and/or `response` are specified, the VTL runtime is used. +When `code` is specified, the JavaScript runtime is used. -If neither are specified, by default, the resolver is a PIPELINE JavaScript resolver, and the following minimalistic resolver handler is used. +When `request` and/or `response` are specified, the VTL runtime is used. + +For [direct lambda](https://docs.aws.amazon.com/appsync/latest/devguide/direct-lambda-reference.html), set `kind` to `UNIT` and don't specify `request`, `response` or `code`. This only works with Lambda function data sources. + +If nothing is specified, by default, the resolver is a PIPELINE JavaScript resolver, and the following minimalistic code is used for the `before` and `after` handlers. ```js export function request() { @@ -49,7 +53,16 @@ export function response(ctx) { } ``` -To use [direct lambda](https://docs.aws.amazon.com/appsync/latest/devguide/direct-lambda-reference.html), set `kind` to `UNIT` and don't specify `request` and `response` (only works with Lambda function data sources). +Example of a UNIT JavaScript resolver. + +```yaml +appSync: + resolvers: + Query.user: + kind: UNIT + dataSource: myDataSource + code: getUser.js +``` ## PIPELINE resolvers diff --git a/src/__tests__/resolvers.test.ts b/src/__tests__/resolvers.test.ts index 28ea5fe5..36ac6634 100644 --- a/src/__tests__/resolvers.test.ts +++ b/src/__tests__/resolvers.test.ts @@ -76,6 +76,62 @@ describe('Resolvers', () => { `); }); + it('should generate JS Resources with specific code', () => { + const api = new Api( + given.appSyncConfig({ + dataSources: { + myTable: { + name: 'myTable', + type: 'AMAZON_DYNAMODB', + config: { tableName: 'data' }, + }, + }, + }), + plugin, + ); + expect( + api.compileResolver({ + type: 'Query', + kind: 'UNIT', + field: 'user', + dataSource: 'myTable', + code: 'resolvers/getUserFunction.js', + }), + ).toMatchInlineSnapshot(` + Object { + "GraphQlResolverQueryuser": Object { + "DependsOn": Array [ + "GraphQlSchema", + ], + "Properties": Object { + "ApiId": Object { + "Fn::GetAtt": Array [ + "GraphQlApi", + "ApiId", + ], + }, + "Code": "Content of resolvers/getUserFunction.js", + "DataSourceName": Object { + "Fn::GetAtt": Array [ + "GraphQlDsmyTable", + "Name", + ], + }, + "FieldName": "user", + "Kind": "UNIT", + "MaxBatchSize": undefined, + "Runtime": Object { + "Name": "APPSYNC_JS", + "RuntimeVersion": "1.0.0", + }, + "TypeName": "Query", + }, + "Type": "AWS::AppSync::Resolver", + }, + } + `); + }); + it('should generate Resources with direct Lambda', () => { const api = new Api( given.appSyncConfig({ diff --git a/src/resources/Resolver.ts b/src/resources/Resolver.ts index 249777d1..1a4039c8 100644 --- a/src/resources/Resolver.ts +++ b/src/resources/Resolver.ts @@ -31,13 +31,22 @@ export class Resolver { FieldName: this.config.field, }; - const isJsResolver = !( - this.config.kind === 'UNIT' || - 'request' in this.config || - 'response' in this.config - ); - - if (!isJsResolver) { + const isVTLResolver = 'request' in this.config || 'response' in this.config; + const isJsResolver = + 'code' in this.config || (!isVTLResolver && this.config.kind !== 'UNIT'); + + if (isJsResolver) { + if (this.config.code) { + Properties.Code = this.resolveJsCode(this.config.code); + } else { + // default for pipeline JS resolvers + Properties.Code = DEFAULT_JS_RESOLVERS; + } + Properties.Runtime = { + Name: 'APPSYNC_JS', + RuntimeVersion: '1.0.0', + }; + } else if (isVTLResolver) { const requestMappingTemplates = this.resolveMappingTemplate('request'); if (requestMappingTemplates) { Properties.RequestMappingTemplate = requestMappingTemplates; @@ -85,18 +94,6 @@ export class Resolver { MaxBatchSize: this.config.maxBatchSize, }; } else { - if (isJsResolver) { - if (this.config.code) { - Properties.Code = this.resolveJsCode(this.config.code); - } else if (!this.config.code) { - Properties.Code = DEFAULT_JS_RESOLVERS; - } - Properties.Runtime = { - Name: 'APPSYNC_JS', - RuntimeVersion: '1.0.0', - }; - } - Properties = { ...Properties, Kind: 'PIPELINE', diff --git a/src/types/plugin.ts b/src/types/plugin.ts index ea56c8b5..f29fbed1 100644 --- a/src/types/plugin.ts +++ b/src/types/plugin.ts @@ -151,6 +151,7 @@ export type BaseResolverConfig = { type: string; request?: string | false; response?: string | false; + code?: string; caching?: | { ttl?: number; @@ -171,7 +172,6 @@ export type UnitResolverConfig = BaseResolverConfig & { export type PipelineResolverConfig = BaseResolverConfig & { kind?: 'PIPELINE'; - code?: string; functions: string[]; };