# Step 16: GraphQL Handler Implementation
**Phase 4: Handler Plugins**
**Estimated Complexity:** High
**Dependencies:** Step 10 (Microservice Handler)
---
## Overview
The GraphQL handler routes GraphQL queries, mutations, and subscriptions to appropriate microservices based on schema analysis. It supports schema stitching, query splitting, and federated execution across multiple services.
---
## Goals
1. Route GraphQL operations to appropriate backend services
2. Support schema federation/stitching across microservices
3. Handle batched queries with DataLoader patterns
4. Support subscriptions via WebSocket upgrade
5. Provide introspection proxying and schema caching
---
## Core Architecture
```
┌──────────────────────────────────────────────────────────────────┐
│ GraphQL Handler │
├──────────────────────────────────────────────────────────────────┤
│ │
│ HTTP Request │
│ │ │
│ ▼ │
│ ┌───────────────┐ │
│ │ Query Parser │──► Extract operation type & fields │
│ └───────┬───────┘ │
│ │ │
│ ▼ │
│ ┌───────────────┐ ┌─────────────────┐ │
│ │ Query Planner │───►│ Schema Registry │ │
│ └───────┬───────┘ └─────────────────┘ │
│ │ │
│ ▼ │
│ ┌───────────────┐ │
│ │Query Executor │──► Split & dispatch to services │
│ └───────┬───────┘ │
│ │ │
│ ▼ │
│ ┌───────────────┐ │
│ │Result Merger │──► Combine partial results │
│ └───────────────┘ │
│ │
└──────────────────────────────────────────────────────────────────┘
```
---
## Configuration
```csharp
namespace StellaOps.Router.Handlers.GraphQL;
public class GraphQLHandlerConfig
{
/// Path prefix for GraphQL endpoint.
public string Path { get; set; } = "/graphql";
/// Whether to enable introspection queries.
public bool EnableIntrospection { get; set; } = true;
/// Whether to enable subscriptions.
public bool EnableSubscriptions { get; set; } = true;
/// Maximum query depth to prevent DOS.
public int MaxQueryDepth { get; set; } = 15;
/// Maximum query complexity score.
public int MaxQueryComplexity { get; set; } = 1000;
/// Timeout for query execution.
public TimeSpan ExecutionTimeout { get; set; } = TimeSpan.FromSeconds(30);
/// Cache duration for schema introspection.
public TimeSpan SchemaCacheDuration { get; set; } = TimeSpan.FromMinutes(5);
/// Whether to enable query batching.
public bool EnableBatching { get; set; } = true;
/// Maximum batch size.
public int MaxBatchSize { get; set; } = 10;
/// Registered GraphQL services and their type ownership.
public Dictionary Services { get; set; } = new();
}
public class GraphQLServiceConfig
{
/// Service name for routing.
public required string ServiceName { get; set; }
/// Root types this service handles (Query, Mutation, Subscription).
public HashSet RootTypes { get; set; } = new();
/// Specific fields this service owns.
public Dictionary> OwnedFields { get; set; } = new();
/// Whether this service provides the full schema.
public bool IsSchemaProvider { get; set; }
}
```
---
## Core Types
```csharp
namespace StellaOps.Router.Handlers.GraphQL;
///
/// Parsed GraphQL request.
///
public sealed class GraphQLRequest
{
public required string Query { get; init; }
public string? OperationName { get; init; }
public Dictionary? Variables { get; init; }
public Dictionary? Extensions { get; init; }
}
///
/// GraphQL response format.
///
public sealed class GraphQLResponse
{
public object? Data { get; set; }
public List? Errors { get; set; }
public Dictionary? Extensions { get; set; }
}
public sealed class GraphQLError
{
public required string Message { get; init; }
public List? Locations { get; init; }
public List