Skip to content

Commit

Permalink
feat: Add JS runtime unit resolver support (#613)
Browse files Browse the repository at this point in the history
Co-authored-by: bboure <[email protected]>
  • Loading branch information
krml4913 and bboure committed Oct 12, 2023
1 parent 227d479 commit 37ae9cd
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 24 deletions.
21 changes: 17 additions & 4 deletions doc/resolvers.md
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand All @@ -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

Expand Down
56 changes: 56 additions & 0 deletions src/__tests__/resolvers.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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({
Expand Down
35 changes: 16 additions & 19 deletions src/resources/Resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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',
Expand Down
2 changes: 1 addition & 1 deletion src/types/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ export type BaseResolverConfig = {
type: string;
request?: string | false;
response?: string | false;
code?: string;
caching?:
| {
ttl?: number;
Expand All @@ -171,7 +172,6 @@ export type UnitResolverConfig = BaseResolverConfig & {

export type PipelineResolverConfig = BaseResolverConfig & {
kind?: 'PIPELINE';
code?: string;
functions: string[];
};

Expand Down

0 comments on commit 37ae9cd

Please sign in to comment.