Architecture
Internal architecture of the GraphQL API layer.
Layered architecture
The GraphQL API follows a layered design where each layer has a clear responsibility:
Apollo Server (HTTP + WebSocket)
│
▼
Schema Layer (Queries, Mutations, Types, Resolvers)
│
▼
Service Layer (Business logic)
│
▼
Facade Layer (Cross-service orchestration)
│
▼
Repository Layer (Data access)
│
▼
Data Sources (RDS via Knex, Athena, Redis, External APIs)
Schema layer
Located in graphql-api/lib/schema/, this layer defines the GraphQL schema programmatically using graphql-js and graphql-compose.
| Directory | Purpose |
|---|---|
queries/ | Query field definitions |
mutations/ | Mutation field definitions |
resolvers/ | Resolver implementations |
types/ | GraphQL object and input type definitions |
dataloaders/ | DataLoader factories for batch loading |
fields/ | Reusable field definitions |
internal/ | Internal-only queries (not exposed externally) |
queriesPrivate/ | Private queries for internal services |
The root schema is assembled in schema/index.ts using GraphQLSchema with query and mutation root types.
Context
Every request creates a GraphQLContext object (schema/GraphQLContext.ts) that contains:
- Database connections — Knex RDS client and Athena client for analytics
- Redis client — for caching and pub/sub
- Services — instantiated per-request business logic services
- Principal — the authenticated user or API key identity
- Access control — permission checks
- DataLoaders — per-request DataLoader instances for batch loading
- Request metadata — unique request ID, headers, IP address
Context is created via schema/createContext/ and passed to every resolver.
Service layer
Located in graphql-api/lib/services/, this layer encapsulates business logic. Services are instantiated per request and injected via the GraphQL context. Key services include:
- Distribution channel management
- Product content and pricing
- Booking lifecycle
- Consumer trip orchestration
- Payment processing
- Entity management
- Search and filtering
Facade layer
Located in graphql-api/lib/facades/, facades coordinate complex operations that span multiple services. They provide a single entry point for multi-step workflows.
Repository layer
Located in graphql-api/lib/repositories/, repositories handle data access using Knex query builder against PostgreSQL (RDS). Each repository is responsible for a specific domain entity.
Plugin architecture
Apollo Server plugins are defined in graphql-api/lib/plugins/:
| Plugin | Purpose |
|---|---|
cloudwatchMetricsPlugin | CloudWatch performance metrics |
datadogPlugin | Datadog APM integration |
sentryPerformanceMetrics | Sentry error and performance tracking |
createErrorHandlerPlugin | Standardised error formatting |
loggerPlugin | Request and operation logging |
Server entry points
The API supports two deployment modes:
- Express server (
graphql-api/server.ts) — for local development and traditional deployments - AWS Lambda handler (
@as-integrations/aws-lambda) — for serverless deployments
Both share the same schema and context creation logic.