aws-appsync-resolver
AWS AppSync JavaScript Resolver Skill
Write resolvers using the AppSync JavaScript (APPSYNC_JS) runtime. Resolvers connect GraphQL operations to data sources using familiar JavaScript syntax.
Core Pattern
Every resolver exports a request function and a response function:
export function request(ctx) {
// Build the data source request using ctx.args, ctx.identity, ctx.source, etc.
return { /* data source request */ };
}
export function response(ctx) {
// Transform and return the data source response
return ctx.result;
}
The ctx (context) object provides:
ctx.args— GraphQL field argumentsctx.result— the data source response (inresponsehandler)ctx.error— error from the data source, if anyctx.identity— caller identity (Cognito, IAM, etc.)ctx.source— parent field value (for nested resolvers)ctx.info— field name, parent type, selection setctx.prev.result— result from previous function (pipeline resolvers)ctx.stash— shared object across pipeline functionsctx.request— request headers
Imports
import { util } from '@aws-appsync/utils';
import * as ddb from '@aws-appsync/utils/dynamodb';
import { sql, select, insert, update, remove, createPgStatement, createMySQLStatement, toJsonObject } from '@aws-appsync/utils/rds';
Only import what you need. The @aws-appsync/utils/dynamodb module provides high-level helpers. The @aws-appsync/utils/rds module provides SQL builders.
Choosing the Right Data Source
| Data Source | When to Use |
|---|---|
| DynamoDB | NoSQL key-value/document storage — most common |
| HTTP | REST APIs, API Gateway, or AWS service APIs (SNS, Translate, etc.) |
| Lambda | Complex business logic that can't run in APPSYNC_JS |
| RDS | Aurora PostgreSQL/MySQL via Data API |
| OpenSearch | Full-text search, geo queries, analytics |
| EventBridge | Event-driven architectures, publish events |
| NONE | Local operations — subscriptions, transforms, no external call |
Read the relevant reference file below for the data source patterns.
Reference Files
Each data source has a dedicated reference with complete code examples. Read the one you need:
references/dynamodb.md— DynamoDB CRUD, queries, batch operations, scans, paginationreferences/http.md— HTTP requests, API Gateway, SNS, AWS Translatereferences/rds.md— Aurora PostgreSQL/MySQL with theselect/sqlbuildersreferences/opensearch.md— Full-text search, geo, paginationreferences/lambda-eventbridge-none.md— Lambda invoke, EventBridge PutEvents, local publish, enhanced subscriptionsreferences/pipeline.md— Pipeline resolvers (chaining multiple functions)
APPSYNC_JS Runtime Restrictions
The APPSYNC_JS runtime does NOT support:
for/while/do...whileloops — use.forEach(),.map(),.filter(),.reduce()insteadArray.sort()— not available; implement merge logic via.forEach()on concatenated arrays- Arrow functions in array method callbacks — can cause
ReferenceErrorfor callback parameters. Always use traditional function expressions:// WRONG — arrow function parameter may be undefined at runtime items.forEach((item) => { doSomething(item) }) // CORRECT — traditional function expression items.forEach(function (item) { doSomething(item) }) try/catch/finally— usectx.errorchecks insteadasync/await— not supported- Classes, generators, symbols, WeakRef,
eval returnValuesin UpdateItem — not supported; error:Unsupported element '$[returnValues]'.ctx.resultafterUpdateItemis empty (no updated attributes). Use optimistic counts on the frontend, or add a follow-upGetItempipeline function to read the updated value
Error Handling
Two patterns depending on severity:
// Hard error — stops execution and returns error to client
if (ctx.error) {
util.error(ctx.error.message, ctx.error.type);
}
// Soft error — appends error but still returns data
util.appendError(body, statusCode);
Common Utilities
util.autoId() // Generate a unique ID
util.time.nowISO8601() // Current timestamp
util.dynamodb.toMapValues({ id }) // Convert JS object to DynamoDB attribute map
util.transform.toSubscriptionFilter() // Build subscription filters
util.xml.toMap(body) // Parse XML to object
util.urlEncode(str) // URL-encode a string
util.http.copyHeaders(ctx.request.headers) // Copy request headers
Development Setup
Install the AppSync utilities for type checking and editor support:
npm install @aws-appsync/utils @aws-appsync/eslint-plugin
Use JSDoc type annotations for better IDE support:
/** @param {import('@aws-appsync/utils').Context<{id: string}>} ctx */
export function request(ctx) { ... }