AppSync GraphQL resolvers can be written in JavaScript instead of VTL. AppSync has dev-time helpers for TypeScript resolvers, but we must bundle the code ourselves.
How can I bundle .ts
resolvers in the CDK?
We pass the resolver code to the CDK AppsyncFunction construct. But we can't directly pass a my-resolver.ts
file. Instead, appsync.Code.fromAsset
needs my-resolver.js
. Right now there isn't a batteries-included esbuild
local bundling option like the one NodejsLambda construct has.
const resolverFunc = new appsync.AppsyncFunction(this, "MyResolverFunc", {
name: "my_resolver",
api,
dataSource: dynamoDataSource,
code: appsync.Code.fromAsset(
path.join(__dirname, "../path/to/my_resolver.ts") // <- ❌ need a .js file here
),
runtime: appsync.FunctionRuntime.JS_1_0_0,
});
Adding to what @fedonev said it's also possible to do this completely inside of CDK, without the need of "external" esbuild.
You can use CDK's feature to bundle assets in a docker container. What you basically do is execute the TypeScript transpilation, eslint, tests, esbuild inside of a docker container and pass the container's output files back to CDK.
Something along the lines of:
api.createResolver('GetTodoResolver', {
typeName: 'Query',
fieldName: 'getTodo',
runtime: appsync.FunctionRuntime.JS_1_0_0,
code: appsync.Code.fromAsset(path.join(__dirname, '..', 'resolvers'), {
bundling: {
outputType: BundlingOutput.SINGLE_FILE,
image: DockerImage.fromRegistry('public.ecr.aws/docker/library/node:18.18.0-slim'),
environment: {
NPM_CONFIG_PREFIX: '/tmp/.npm-global',
NPM_CONFIG_CACHE: '/tmp/.npm-cache',
},
command: ['bash', '-c', ['npm install', 'npm run dist', 'cp dist/appsync/* /asset-output',].join(' && '),],
}
}),
dataSource: noneDS
});
There's also a blog post available which describes the bundling approach in more detail: https://aws.amazon.com/blogs/devops/building-apps-with-aws-cdk/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With