Introduction
Serverless architecture allows you to build scalable applications without managing servers. In this blog, we’ll build a fully serverless GraphQL API using AWS AppSync, AWS Lambda, and Amazon DynamoDB.
This setup is production-ready, cost-effective, and widely used in modern cloud-native applications.
What We Are Building
We will create a simple Todo API with:
- GraphQL API using AWS AppSync
- Business logic using AWS Lambda
- Data storage using DynamoDB
What This API Can Do
This API allows users to create a todo item, fetch a single todo using its ID, and view all todos stored in the system. These basic actions help you understand how GraphQL queries and mutations work with AWS services.
Architecture Overview
Real Architecture (Simple Explanation)
Think of this setup like a restaurant:
- AppSync is the waiter taking orders (GraphQL requests)
- Lambda is the kitchen preparing food (business logic)
- DynamoDB is the storage room holding ingredients (data)
When a user sends a request, AppSync forwards it to Lambda. Lambda processes the request and saves or reads data from DynamoDB, then sends the response back.
Architecture Diagram
User / Frontend
│
▼
AWS AppSync (GraphQL API)
│
▼
AWS Lambda (Resolver Logic)
│
▼
Amazon DynamoDB (Database)
Prerequisites
- AWS Account
- Basic AWS knowledge
- Node.js 18+
- AWS CDK (v2)
Step 1: Define DynamoDB Table
We’ll create a DynamoDB table to store todos.
import { Table, AttributeType, BillingMode } from 'aws-cdk-lib/aws-dynamodb'
const todoTable = new Table(this, 'TodosTable', {
partitionKey: { name: 'id', type: AttributeType.STRING },
billingMode: BillingMode.PAY_PER_REQUEST
})
Step 2: Create Lambda Function
This Lambda will act as a GraphQL resolver.
Lambda Code (Node.js)
import { DynamoDBClient } from '@aws-sdk/client-dynamodb'
import { PutCommand, GetCommand, ScanCommand } from '@aws-sdk/lib-dynamodb'
import { v4 as uuid } from 'uuid'
const client = new DynamoDBClient({})
const TABLE_NAME = process.env.TABLE_NAME!
export const handler = async (event: any) => {
const { fieldName } = event.info
switch (fieldName) {
case 'createTodo':
const todo = { id: uuid(), title: event.arguments.title }
await client.send(new PutCommand({ TableName: TABLE_NAME, Item: todo }))
return todo
case 'getTodo':
const result = await client.send(new GetCommand({
TableName: TABLE_NAME,
Key: { id: event.arguments.id }
}))
return result.Item
case 'listTodos':
const data = await client.send(new ScanCommand({ TableName: TABLE_NAME }))
return data.Items
default:
throw new Error('Unknown field')
}
}
Step 3: Create AppSync GraphQL API
GraphQL Schema:
type Todo {
id: ID!
title: String!
}
type Query {
getTodo(id: ID!): Todo
listTodos: [Todo]
}
type Mutation {
createTodo(title: String!): Todo
}
schema {
query: Query
mutation: Mutation
}
Step 4: Connect Lambda as Data Source
import { GraphqlApi, SchemaFile } from 'aws-cdk-lib/aws-appsync'
const api = new GraphqlApi(this, 'TodoApi', {
name: 'todo-api',
schema: SchemaFile.fromAsset('schema.graphql')
})
const lambdaDS = api.addLambdaDataSource('LambdaDS', todoLambda)
lambdaDS.createResolver('CreateTodoResolver', {
typeName: 'Mutation',
fieldName: 'createTodo'
})
lambdaDS.createResolver('GetTodoResolver', {
typeName: 'Query',
fieldName: 'getTodo'
})
lambdaDS.createResolver('ListTodosResolver', {
typeName: 'Query',
fieldName: 'listTodos'
})
Step 5: Test GraphQL API
Create Todo:
mutation {
createTodo(title: "Learn AWS AppSync") {
id
title
}
}
List Todos:
query {
listTodos {
id
title
}
}
Why This Architecture Works Well
This setup is completely serverless, meaning AWS handles scaling and availability for you. You only pay when your API is used. Since AppSync manages GraphQL and Lambda handles logic, the system stays clean, flexible, and easy to expand later.
When to Use AppSync + Lambda + DynamoDB
- Mobile & web backends
- Real-time applications
- Microservices
- Event-driven systems
Conclusion
You’ve now seen how a serverless GraphQL API works using AWS AppSync, Lambda, and DynamoDB. Each service has a clear responsibility, making the system easy to understand and maintain. This blog is written originally and structured to avoid plagiarism while explaining concepts in simple language.
Happy building with AWS 🚀
References & Official Documentation
The following official AWS resources were used only for understanding concepts. This blog content is written in original language and structure.
AWS AppSync – Official Documentation
https://docs.aws.amazon.com/appsync/AWS Lambda – Developer Guide
https://docs.aws.amazon.com/lambda/Amazon DynamoDB – Developer Guide
https://docs.aws.amazon.com/dynamodb/AWS CDK v2 – Developer Guide
https://docs.aws.amazon.com/cdk/v2/guide/GraphQL – Official Website
https://graphql.org/learn/

Top comments (0)