Architectural Design of the AppSync GraphQL API for Web UI Data Communication
The web UI communicates with the backend exclusively through an AWS AppSync GraphQL API defined in nested/appsync/template.yaml, utilizing Cognito User Pools for authentication, DynamoDB and Lambda data sources for business logic, and real-time subscriptions for live updates.
The accelerated-intelligent-document-processing-on-aws solution implements a robust communication layer that connects the React frontend to backend services. The architectural design of the AppSync GraphQL API for web UI data communication centers on a nested CloudFormation stack that provisions a single, secure endpoint for all document processing operations while enforcing fine-grained authorization at the field level.
AppSync GraphQL API Overview
The API is generated from a nested CloudFormation stack located at nested/appsync/template.yaml. This stack receives the core API identifiers—including GraphQLApiId, GraphQLApiArn, and GraphQLApiUrl—as parameters from the main deployment template at lines 5-18. The nested stack then extends the API with schema definitions, data sources, and resolver mappings that handle queries, mutations, and subscriptions.
Core Architectural Components
GraphQL Schema Definition
The schema is defined in nested/appsync/src/api/schema.graphql and declares all Types, Queries, Mutations, and Subscriptions required by the UI. Every field is annotated with @aws_cognito_user_pools or @aws_iam directives to enforce authentication and authorization at the field level.
For example, the Query type definition at lines 59-62 includes these security directives:
type Query @aws_cognito_user_pools @aws_iam {
getDocument(ObjectKey: ID!): Document
listDocuments: [Document]
}
Data Sources
The architecture supports three primary data source types, each defined in nested/appsync/template.yaml starting around line 505:
- DynamoDB Tables: Direct integrations with Tracking, Configuration, Agent, and Chat tables for low-latency reads and writes.
- Lambda Functions: Business logic resolvers for complex operations like document creation, chat interactions, and agent handling.
- None: Used for subscription resolvers that leverage AppSync's built-in publish/subscribe mechanism without backing data stores.
Resolver Mapping
Resolvers map every GraphQL operation to its corresponding data source using Apache Velocity Template Language (VTL) templates defined in the CloudFormation template. For instance, the createDocument mutation resolver defined at lines 2121-2127 in template.yaml points to the CreateDocumentDataSource, which invokes the CreateDocumentResolverFunction Lambda.
IAM and Security Roles
The AppSyncServiceRole defined in nested/appsync/template.yaml at lines 1818-1846 trusts the AppSync service principal and grants minimal permissions to:
- Read and write DynamoDB tables
- Invoke Lambda functions
- Decrypt KMS keys
This role is referenced by every data source to ensure least-privilege access across the API.
Data Flow Architecture
The communication flow between the React UI and backend services follows this pattern:
- Request Initiation: The React UI issues a GraphQL request to the
GraphQLApiUrlendpoint, signing the request with a Cognito JWT token. - Authorization: AppSync validates the JWT and checks field-level directives to determine whether the caller requires Cognito authentication or IAM policies for admin-only operations.
- Resolver Execution: The appropriate resolver processes the request through either direct DynamoDB access for simple queries or Lambda invocation for business logic.
- Backend Integration: Lambda functions interact with S3, Bedrock, Step Functions, and other AWS services using their execution roles.
- Response: Data returns through the resolver chain, conforming to the GraphQL schema types.
- Real-time Updates: For subscriptions, AppSync pushes payloads to subscribed clients when mutation events occur.
Implementation Examples
Querying Document Data
To retrieve a specific document, the UI executes this GraphQL query:
query GetDocument($key: ID!) {
getDocument(ObjectKey: $key) {
PK
SK
ObjectKey
WorkflowStatus
Pages {
Id
TextUri
}
}
}
This query resolves to the TrackingTableDataSource in DynamoDB.
Creating Documents via Mutation
Document creation uses a Lambda resolver to orchestrate the ingestion workflow:
mutation CreateDoc($inp: CreateDocumentInput!) {
createDocument(input: $inp) {
ObjectKey
}
}
The resolver maps to CreateDocumentDataSource, invoking the CreateDocumentResolverFunction Lambda defined in nested/appsync/template.yaml.
Real-time Subscriptions
Clients subscribe to document creation events for live UI updates:
subscription OnCreate {
onCreateDocument {
presignedUrl
objectKey
}
}
This subscription uses the None data source and AppSync's built-in publish mechanism, triggered by the createDocument mutation.
Client Integration with AWS Amplify
The React UI uses AWS Amplify to handle authentication and API calls:
import { API, graphqlOperation } from 'aws-amplify';
import { getDocument } from '@/graphql/queries';
async function fetchDoc(key) {
const result = await API.graphql(
graphqlOperation(getDocument, { ObjectKey: key })
);
console.log('Document:', result.data.getDocument);
}
Amplify automatically attaches the Cognito JWT to the request headers, satisfying the @aws_cognito_user_pools authorization requirements.
Key Source Files and Repository Structure
The AppSync implementation resides in the nested/appsync/ directory of the aws-solutions-library-samples/accelerated-intelligent-document-processing-on-aws repository:
nested/appsync/template.yaml– CloudFormation nested stack defining AppSync resources, data sources, resolvers, and theAppSyncServiceRole(lines 1818-1846).nested/appsync/src/api/schema.graphql– Complete GraphQL schema with type definitions and authorization directives (e.g.,type Query @aws_cognito_user_pools @aws_iamat lines 59-62).nested/appsync/src/lambda/– Business logic resolvers including:create_document_resolver/– Document ingestion orchestrationchat_with_document_resolver/– Conversational AI interactionssend_agent_chat_message_resolver/– Agent messaging functionality
src/ui/– React frontend application configured to communicate with the AppSync endpoint via AWS Amplify.
Summary
- The AppSync GraphQL API serves as the exclusive communication layer between the React web UI and backend services in the accelerated-intelligent-document-processing-on-aws solution.
- The architecture uses a nested CloudFormation stack (
nested/appsync/template.yaml) to define the API schema, data sources, and resolver mappings. - Authentication relies on Cognito User Pools (
@aws_cognito_user_pools) for UI access and IAM (@aws_iam) for service-to-service calls, enforced at the field level through schema directives. - Data sources include DynamoDB tables for direct data access, Lambda functions for business logic, and the
Nonetype for real-time subscriptions. - Real-time capabilities are implemented via GraphQL subscriptions that push updates to clients when mutations occur, enabling live document status and chat functionality without polling.
Frequently Asked Questions
How does the AppSync API authenticate requests from the web UI?
The API uses Amazon Cognito User Pools as the primary authentication mechanism. The React UI obtains a JWT token from Cognito and includes it in the Authorization header. The GraphQL schema enforces this through the @aws_cognito_user_pools directive applied to types and fields. For internal service-to-service communication, the API also supports IAM authentication via the @aws_iam directive.
What AWS services does the AppSync API interact with to process documents?
The API interacts with multiple backend services through its data sources. DynamoDB tables store document metadata, configuration settings, and chat history. Lambda functions orchestrate complex workflows including document creation, conversational AI interactions with Amazon Bedrock, and agent messaging. The API also facilitates S3 access for document storage and Step Functions for workflow orchestration, though these are typically accessed via the Lambda resolvers rather than directly.
How are real-time updates implemented in the AppSync architecture?
Real-time updates use GraphQL subscriptions combined with the None data source type. When a mutation such as createDocument executes successfully, AppSync automatically publishes the event to all clients subscribed to onCreateDocument. The subscription resolver uses the None data source because it does not need to fetch data from a backend service—AppSync handles the pub/sub mechanism internally. This pattern enables live UI updates for document status changes and chat messages without polling.
Where is the AppSync API defined in the repository source code?
The API definition resides in the nested/appsync/ directory of the aws-solutions-library-samples/accelerated-intelligent-document-processing-on-aws repository. The CloudFormation template at nested/appsync/template.yaml defines the API resources, data sources, resolvers, and IAM roles. The GraphQL schema is located at nested/appsync/src/api/schema.graphql. Business logic implemented in Lambda resides in nested/appsync/src/lambda/, with specific functions for document creation, chat, and agent messaging. The React frontend code that consumes this API is located in src/ui/.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →