Appsync Repo 【720p】
AWS AppSync is a managed GraphQL service with real-time subscriptions, offline support, and data sync. This paper examines how the repository pattern can be implemented in AppSync-backed applications to abstract data sources (DynamoDB, Lambda, Aurora, HTTP) and enable testable, scalable GraphQL resolvers.
A pipeline resolver chains multiple functions together. In your repo, store each pipeline function in functions/ and the main resolver in resolvers/pipelines/. Example use case: fetch user profile → enrich with permissions → fetch posts.
Traditional REST repositories hide data access logic. In AppSync, resolvers (VTL or JavaScript) act as the repository layer. The challenge: maintaining separation of concerns when business logic sits in resolver code or Lambda functions. appsync repo
This write-up explains the architecture and benefits of a well-structured AppSync repository.
The schema.graphql file is the heart of your AppSync repo. Do not write it as one monolithic file. Use #import syntax (supported by AWS Amplify and CDK) to split it. AWS AppSync is a managed GraphQL service with
Example: types/user.graphql
type User @model
id: ID!
email: String! @aws_cognito_user_pools
profilePic: String
posts: [Post] @hasMany
Best Practice: Store enums, inputs, and interfaces in separate files. Use schema linting in your CI pipeline (graphql-schema-linter). The schema
Here is a battle-tested folder structure for an enterprise-grade AppSync repository.
appsync-repo/
├── .github/ # CI/CD workflows (GitHub Actions)
├── infrastructure/ # IaC (CDK, Terraform, SAM)
│ ├── stacks/
│ │ ├── api-stack.ts # Creates AppSync API
│ │ ├── datasource-stack.ts# DynamoDB, RDS, Elasticsearch
│ │ └── auth-stack.ts # Cognito User Pools, IAM roles
│ └── config/ # Environment-specific variables
│ ├── dev.json
│ ├── staging.json
│ └── prod.json
├── schema/ # GraphQL schema definition
│ ├── schema.graphql # Root schema
│ ├── types/
│ │ ├── user.graphql
│ │ ├── product.graphql
│ │ └── order.graphql
│ └── directives/ # Custom @aws_* directives
├── resolvers/ # Resolver logic (VTL or JS)
│ ├── functions/ # Pipeline resolver functions
│ │ ├── getUser.js
│ │ ├── createProduct.js
│ │ └── validateOrder.vtl
│ └── mappings/ # Request/response templates
│ ├── request.vtl
│ └── response.vtl
├── functions/ # Lambda resolvers (Code)
│ ├── getOrders/
│ │ ├── index.py
│ │ └── requirements.txt
│ └── processPayment/
│ ├── index.js
│ └── package.json
├── tests/ # Integration & unit tests
│ ├── queries/
│ │ └── getProduct.graphql
│ ├── mutations/
│ └── subscriptions/
├── scripts/ # Utility scripts
│ ├── seed-database.js
│ └── validate-schema.sh
└── README.md # Onboarding & runbooks
This boilerplate supports multiple authorization modes:
Edit the authorizationConfig in infrastructure/lib/appsync-stack.ts to toggle modes.
| Pattern | Implementation | Use case |
|---------|---------------|-----------|
| Single-table repository | Single DynamoDB table with PK/SK + GSIs | Multi-entity domain (e.g., users, posts, comments) |
| CQRS repository | Separate read (DynamoDB + GSI) and write (DynamoDB + streams) | High-scale read/write asymmetry |
| Event-driven repository | Save to DynamoDB + publish to EventBridge | Integration with event sourcing |
| Offline repository | AWSAppSyncClient + local store (SQLite/IndexedDB) | Mobile/web with sync conflict resolution |