DVA-C02Chapter 49 of 101Objective 1.2

AWS AppSync GraphQL and Real-Time Subscriptions

This chapter covers AWS AppSync, a fully managed service that enables you to build real-time and offline-capable applications using GraphQL. For the DVA-C02 exam, AppSync appears in roughly 5-8% of questions, primarily in Domain 1 (Development) under Objective 1.2: "Develop applications using AWS AppSync." You will be tested on how to define GraphQL schemas, configure data sources, implement resolvers (including pipeline resolvers), set up real-time subscriptions, and manage authentication and authorization. This chapter provides the deep understanding needed to answer scenario-based questions about building scalable, real-time APIs.

25 min read
Intermediate
Updated May 31, 2026

AppSync as a Smart Message Broker

Imagine a stock exchange trading floor where traders need instant updates on stock prices. Instead of each trader constantly calling the exchange to ask "What's the price of AAPL now?" (polling), the exchange installs a smart message board system. Each trader can subscribe to specific stocks by pressing a button on their desk. When a stock price changes, the exchange's central computer sends the update to a message broker, which then pushes the new price to all subscribed traders' screens simultaneously. This broker also handles complex requests: if a trader asks "Show me all stocks that went up more than 5% today," the broker translates that into a query, fetches the data from the database, and returns the result. It also caches frequently accessed data so that if multiple traders ask the same question, it serves from cache. In AWS terms, the exchange is your backend data sources (DynamoDB, Lambda, etc.), the message broker is AWS AppSync, the subscription buttons are GraphQL subscriptions, and the complex queries are GraphQL queries and mutations. AppSync manages real-time connections via WebSockets, automatically reconnecting if a trader's connection drops, and handles authorization to ensure only authorized traders see certain data.

How It Actually Works

What is AWS AppSync?

AWS AppSync is a managed GraphQL service that simplifies application development by providing a single endpoint to query, mutate, and subscribe to data from multiple sources. It supports real-time updates via WebSockets, offline data synchronization for mobile/web apps, and fine-grained access control. AppSync acts as a GraphQL server that translates client requests into operations against backend data sources such as Amazon DynamoDB, AWS Lambda, Amazon OpenSearch, or any HTTP endpoint.

GraphQL Primer

GraphQL is a query language for APIs that allows clients to request exactly the data they need. Unlike REST, which exposes multiple endpoints, GraphQL exposes a single endpoint and lets clients specify their data requirements. A GraphQL schema defines types (e.g., type User { id: ID!, name: String }), queries (read operations), mutations (write operations), and subscriptions (real-time events). AppSync uses this schema to generate a fully functional API.

How AppSync Works Internally

When a client sends a GraphQL request to AppSync, the service parses the query, validates it against the schema, and then executes it by invoking resolvers. Resolvers are functions that map GraphQL fields to data sources. AppSync supports two resolver types: - Unit resolvers: A single resolver that directly maps a field to a data source operation (e.g., a DynamoDB GetItem). - Pipeline resolvers: A chain of functions (called functions) that execute sequentially, passing data between them. Each function can be a VTL (Apache Velocity Template Language) template or an AppSync JavaScript function (since late 2022).

The resolver is written in VTL or JavaScript and defines the request and response mapping templates. The request template specifies how to transform the GraphQL arguments into a request to the data source (e.g., a DynamoDB Query). The response template transforms the data source response back into GraphQL format.

Data Sources

AppSync supports the following data sources: - Amazon DynamoDB: Directly query/update tables. - AWS Lambda: Invoke a Lambda function with custom logic. - Amazon OpenSearch Service: Full-text search. - Amazon RDS: Via Lambda or HTTP resolver using Data API. - HTTP: Any REST endpoint. - None: For static data or custom resolvers.

Each data source is configured with a service role ARN that grants AppSync permissions to access the resource.

Real-Time Subscriptions

Subscriptions are a GraphQL feature that allows clients to receive real-time updates when specific mutations occur. In AppSync, subscriptions are implemented using WebSockets. When a client subscribes to a field, AppSync establishes a persistent WebSocket connection. When a mutation that matches the subscription criteria is executed, AppSync pushes the result to all subscribed clients.

Subscription definitions in the schema look like:

type Subscription {
    onNewMessage(roomId: ID!): Message
        @aws_subscribe(mutation: "sendMessage")
}

The @aws_subscribe directive links the subscription to a specific mutation. When sendMessage mutation is called, AppSync checks if any active subscriptions match the roomId argument and delivers the new message.

Authentication and Authorization

AppSync integrates with multiple authentication providers: - AWS IAM: For server-to-server communication. - Amazon Cognito User Pools: For user authentication. - OpenID Connect (OIDC): For federated identity. - API Key: For public or development access.

You can also use multiple auth modes on a single API (e.g., IAM for admin operations, Cognito for user operations). Authorization can be further controlled at the resolver level using VTL or JavaScript to check claims from the JWT token.

Offline Data Sync

AppSync provides client SDKs (for iOS, Android, JavaScript, etc.) that enable offline capabilities. The SDK caches data locally and synchronizes changes when connectivity is restored. It uses a local store and a conflict resolution strategy (e.g., "optimistic concurrency" or "last writer wins") to handle conflicts.

Key Features for the Exam

Pipeline resolvers: Understand how to chain functions for complex workflows (e.g., validate input then write to DB).

VTL vs JavaScript: AppSync now supports JavaScript resolvers (since Dec 2022). Exam may test differences.

Subscription filtering: Subscriptions can filter based on arguments (e.g., roomId).

Caching: AppSync supports caching at the API level (TTL configurable, default 1 minute).

Logging and Monitoring: Integrates with CloudWatch Logs and X-Ray for tracing.

Configuration Example

Creating an AppSync API with DynamoDB data source via AWS CLI:

aws appsync create-graphql-api --name MyAPI --authentication-type API_KEY
aws appsync create-data-source --api-id <api-id> --name MyTable --type AMAZON_DYNAMODB \
    --dynamodb-config tableName=MyTable,awsRegion=us-east-1
aws appsync create-resolver --api-id <api-id> --type-name Query --field-name getItem \
    --request-mapping-template '{"version":"2017-02-28","operation":"GetItem","key":{"id":$util.dynamodb.toDynamoDBJson($ctx.args.id)}}' \
    --response-mapping-template '$util.toJson($ctx.result)'

Related Services

AWS Amplify: Provides higher-level abstractions for AppSync.

Amazon API Gateway: Alternative for REST/HTTP APIs, but lacks native GraphQL and real-time subscriptions.

AWS IoT Core: For IoT-specific real-time messaging, but AppSync is more general-purpose.

Walk-Through

1

Define GraphQL Schema

Start by creating a GraphQL schema that defines the types, queries, mutations, and subscriptions your API will expose. The schema is written in GraphQL Schema Definition Language (SDL). For example, a simple schema for a chat app might include a `Message` type with `id`, `content`, `author`, and `timestamp` fields, a `Query` type with a `getMessages(roomId: ID!)` field, a `Mutation` type with a `sendMessage(roomId: ID!, content: String!, author: String!)` field, and a `Subscription` type with an `onNewMessage(roomId: ID!)` field decorated with `@aws_subscribe(mutation: "sendMessage")`. The schema must be uploaded to AppSync via the console, CLI, or CloudFormation.

2

Configure Data Sources

After defining the schema, configure the backend data sources. For each data source, specify the type (e.g., DynamoDB, Lambda, HTTP) and the connection details. For DynamoDB, provide the table name and region. For Lambda, provide the function ARN. AppSync will need an IAM role (service role) with permissions to access these resources. You can create multiple data sources for different parts of the schema. For example, a chat app might use a DynamoDB table for messages and a Lambda function for user validation.

3

Create Resolvers

Resolvers map GraphQL fields to data source operations. For each field in the schema that requires data fetching or mutation, attach a resolver. Resolvers consist of request and response mapping templates written in VTL or JavaScript. The request template defines how to transform the GraphQL arguments into a data source request (e.g., a DynamoDB GetItem call). The response template transforms the data source response back into the GraphQL shape. For subscriptions, no resolver is needed; the `@aws_subscribe` directive links the subscription to a mutation.

4

Set Authentication and Authorization

Choose an authentication mode for your API: API key, IAM, Cognito User Pools, or OIDC. For production, Cognito User Pools is common. You can also enable multiple auth modes. After setting the global auth mode, you can further restrict access at the resolver level using `$ctx.identity` to check user claims. For example, in a VTL resolver, you can check if the user is an admin before allowing a delete mutation.

5

Test and Deploy

Use the AppSync console's query editor to test your API. You can run queries, mutations, and subscribe to real-time events. Monitor the API via CloudWatch Logs and X-Ray traces. Once verified, deploy the API to production. AppSync supports versioning and canary deployments via AWS CodeDeploy. Also, consider enabling caching (default TTL 60 seconds) to reduce latency and cost.

What This Looks Like on the Job

Enterprise Scenario 1: Real-Time Chat Application

A large enterprise deploys a customer support chat system using AppSync. The schema defines Message and Conversation types. Queries fetch conversation history from DynamoDB, mutations send new messages, and subscriptions push new messages to all participants in real time. The system uses Cognito User Pools for authentication, with fine-grained authorization ensuring users only see their own conversations. At scale, the system handles 10,000 concurrent WebSocket connections. Performance considerations include using DynamoDB's auto-scaling and AppSync's caching to reduce read load. Misconfiguration often occurs when the subscription filter argument (e.g., conversationId) is omitted, causing all clients to receive all messages.

Enterprise Scenario 2: E-Commerce Product Catalog

An e-commerce platform uses AppSync to serve product data to mobile and web clients. The GraphQL schema allows clients to query products with filters (category, price range) and mutations to add reviews. The data source is a combination of DynamoDB (product details) and OpenSearch (full-text search). Pipeline resolvers are used to first validate the user's session via a Lambda function, then query DynamoDB. Subscriptions notify users when a product's price drops below a threshold. The system serves 50,000 queries per second with 99.9% uptime. Common pitfalls include not setting proper TTL on subscriptions, leading to stale connections, and misconfiguring the VTL templates for complex joins.

Enterprise Scenario 3: IoT Dashboard

A smart building company uses AppSync to provide real-time sensor data to a dashboard. Sensors publish data to AWS IoT Core, which triggers a Lambda function that writes to DynamoDB. AppSync subscriptions push updates to the dashboard. The schema includes a SensorReading type with deviceId, timestamp, value. The subscription is filtered by deviceId. The system must handle intermittent connectivity; the AppSync client SDK's offline capabilities cache the last known values and sync when reconnected. A common issue is not enabling conflict resolution, which causes data loss when multiple clients update the same sensor reading.

How DVA-C02 Actually Tests This

What the DVA-C02 Tests

Objective 1.2 focuses on developing applications using AppSync. Expect scenario-based questions about:

Choosing the correct resolver type (unit vs pipeline).

Understanding subscription filtering and the @aws_subscribe directive.

Configuring authentication (especially Cognito vs IAM vs API Key).

Implementing offline sync and conflict resolution.

Using VTL or JavaScript in resolvers.

Common Wrong Answers

1.

"Use API Gateway for real-time APIs" – API Gateway does not natively support GraphQL or WebSocket subscriptions; AppSync is the correct service.

2.

"AppSync subscriptions require a Lambda data source" – Subscriptions are triggered by mutations, regardless of data source.

3.

"Pipeline resolvers are only for DynamoDB" – They work with any data source.

4.

"AppSync cannot integrate with RDS" – It can via Lambda or HTTP resolver.

Specific Exam Values

Default cache TTL: 60 seconds.

Maximum WebSocket connection duration: 1 hour (idle timeout).

Subscription filtering is based on mutation arguments.

VTL templates use $ctx.args, $ctx.result, $ctx.identity.

Edge Cases

When using multiple auth modes, the client must specify which mode to use via a header.

Offline sync conflict resolution: "optimistic concurrency" uses version numbers; "last writer wins" overwrites blindly.

For subscriptions, if a mutation returns a type that does not match the subscription field, the subscription will not be triggered.

How to Eliminate Wrong Answers

If the question mentions "real-time updates" and "GraphQL," the answer is AppSync, not API Gateway.

If the question asks about "offline support," look for AppSync client SDK features.

If the question involves "multiple data sources in one query," think pipeline resolvers.

Key Takeaways

AppSync is a managed GraphQL service that supports real-time subscriptions via WebSockets.

Resolvers map GraphQL fields to data sources using VTL or JavaScript templates.

The @aws_subscribe directive links a subscription field to a specific mutation.

Authentication options: API Key, IAM, Cognito User Pools, OIDC.

Default cache TTL is 60 seconds when caching is enabled.

Pipeline resolvers allow chaining multiple functions for complex operations.

Offline sync uses client SDKs with conflict resolution (optimistic concurrency or last writer wins).

Easy to Mix Up

These come up on the exam all the time. Here's how to tell them apart.

AWS AppSync

Native GraphQL support.

Built-in real-time subscriptions via WebSockets.

Offline data sync with client SDKs.

Supports multiple data sources with resolvers.

Fine-grained authorization at resolver level.

Amazon API Gateway

REST and HTTP APIs only.

WebSocket support requires manual configuration (API Gateway WebSocket API).

No native offline sync; must be implemented separately.

Integrates with Lambda, HTTP, but not directly with DynamoDB or OpenSearch.

Authorization via IAM, Cognito, Lambda authorizer at API level.

Watch Out for These

Mistake

AppSync only works with DynamoDB.

Correct

AppSync supports multiple data sources: DynamoDB, Lambda, OpenSearch, HTTP, RDS (via Lambda), and None.

Mistake

Subscriptions require a dedicated WebSocket API.

Correct

AppSync automatically manages WebSocket connections for subscriptions. You only need to define the subscription in the GraphQL schema.

Mistake

Pipeline resolvers are slower than unit resolvers.

Correct

Pipeline resolvers allow chaining multiple operations in a single request, reducing round trips. They can be faster for complex workflows.

Mistake

You cannot use JavaScript resolvers with AppSync.

Correct

Since December 2022, AppSync supports JavaScript resolvers as an alternative to VTL.

Mistake

AppSync caches all queries automatically.

Correct

Caching must be explicitly enabled and configured with a TTL (default 60 seconds). It caches responses per query string.

Do You Actually Know This?

Reveal each answer, then mark whether you got it right. Score 60%+ to unlock the next chapter.

Frequently Asked Questions

How do I set up real-time subscriptions in AppSync?

Define a subscription type in your GraphQL schema with the @aws_subscribe directive pointing to a mutation. For example: `type Subscription { onNewMessage(roomId: ID!): Message @aws_subscribe(mutation: "sendMessage") }`. When the `sendMessage` mutation is executed, AppSync pushes the result to all clients subscribed to `onNewMessage` with matching `roomId`. Clients connect via WebSocket using the AppSync SDK.

Can I use AppSync with an existing REST API?

Yes, you can use the HTTP data source to connect AppSync to any REST endpoint. You will need to write resolvers that transform GraphQL requests into HTTP calls and parse the responses. This is useful for integrating with legacy systems.

What is the difference between unit and pipeline resolvers?

A unit resolver directly maps a single GraphQL field to a single data source operation. A pipeline resolver chains multiple functions (each with its own request/response mapping) that execute sequentially. Pipeline resolvers are useful for complex workflows like validation, enrichment, and multiple data source access in one request.

How does AppSync handle authentication?

AppSync supports four authentication modes: API Key (simple, for development), AWS IAM (for server-to-server), Amazon Cognito User Pools (for user authentication), and OpenID Connect (for federated identity). You can also enable multiple modes on a single API, where the client selects which mode to use via a header or the SDK.

What is the maximum WebSocket connection duration for AppSync subscriptions?

The idle timeout for a WebSocket connection is 1 hour. If no data is sent for 1 hour, the connection is closed. The client SDK automatically reconnects when needed. For active subscriptions, the connection stays open indefinitely.

Can I use AppSync offline?

Yes, the AppSync client SDKs (for iOS, Android, JavaScript) provide offline capabilities. They cache data locally and synchronize changes when connectivity is restored. You can configure conflict resolution strategies: optimistic concurrency (uses version numbers) or last writer wins.

How do I debug AppSync resolvers?

Enable CloudWatch Logs for your AppSync API. Each resolver execution logs the request and response templates, as well as any errors. You can also use AWS X-Ray for tracing to see end-to-end latency. For VTL templates, you can add logging using `$util.log.info()`.

Terms Worth Knowing

Ready to put this to the test?

You've just covered AWS AppSync GraphQL and Real-Time Subscriptions — now see how well it sticks with free DVA-C02 practice questions. Full explanations included, no account needed.

Done with this chapter?