GraphQL Module API Reference
September 17, 2026 · View on GitHub
GqlModule
Overview
Main NestJS module that provides GraphQL API functionality with Neo4j integration.
Dependencies
@nestjs/graphql- GraphQL integration for NestJS@neo4j/graphql- Neo4j GraphQL libraryapollo-server-express- Apollo GraphQL server
Module Configuration
@Module({
imports: [
ConfigModule.forFeature(gqlConfig),
DatabaseModule,
CustomResolverModule,
GraphQLModule.forRootAsync<ApolloDriverConfig>({...})
],
providers: [],
exports: []
})
Environment Variables
| Variable | Type | Default | Description |
|---|---|---|---|
NODE_ENV | string | development | Application environment |
NEO4J_URI | string | required | Neo4j database connection URI |
NEO4J_USERNAME | string | required | Neo4j username |
NEO4J_PASSWORD | string | required | Neo4j password |
OIDC_JWKS_URI | string | optional | OIDC JWKS endpoint for JWT validation |
GQL_SCHEMA_PATH | string | schema/schema.graphql | Path to GraphQL schema file |
GQL_QUERY_DEPTH_LIMIT | number | 10 | Maximum query nesting depth |
GQL_QUERY_COMPLEXITY_LIMIT | number | 1000 | Maximum query complexity score |
GQL_ENABLE_SUBSCRIPTIONS | boolean | true | Enable GraphQL subscriptions |
GqlConfig
Overview
Configuration class with validation for GraphQL module settings.
Properties
class GqlConfig {
schemaPath: string; // Path to GraphQL schema file
playground: boolean; // Enable GraphQL Playground
introspection: boolean; // Enable schema introspection
oidcJwksUri?: string; // OIDC JWKS URI for JWT validation
queryDepthLimit: number; // Maximum query depth
queryComplexityLimit: number; // Maximum query complexity
enableSubscriptions: boolean; // Enable WebSocket subscriptions
}
Methods
// Factory function that creates and validates configuration
export default registerAs('gql', () => GqlConfig)
Validation Rules
schemaPathmust be a non-empty stringplaygroundandintrospectionmust be booleansoidcJwksUrimust be a valid string if providedqueryDepthLimitmust be a positive numberqueryComplexityLimitmust be a positive numberenableSubscriptionsmust be a boolean
SchemaService
Overview
Service responsible for GraphQL schema creation, validation, and resolver integration.
Constructor
constructor(
private readonly configService: ConfigService,
@Inject('NEO4J_DRIVER') private readonly neo4jDriver: any
)
Methods
buildSchemaWithResolvers(customResolvers: ResolverMap): Promise<any>
Creates a complete GraphQL schema with custom resolvers integrated.
Parameters:
customResolvers: ResolverMap- Map of custom resolver functions
Returns: Promise<any> - Executable GraphQL schema
Process:
- Loads GraphQL schema from file
- Validates Neo4j connection
- Creates Neo4j GraphQL instance with resolvers
- Returns executable schema
Throws:
Error- If schema file not found or invalidError- If Neo4j connection failsError- If schema compilation fails
getSchema(): Promise<any>
Gets cached schema or builds new one without custom resolvers.
Returns: Promise<any> - Executable GraphQL schema
Note: Uses empty resolver map {} for basic schema
validateSchema(): Promise<boolean>
Validates schema without building it completely.
Returns: Promise<boolean> - True if schema is valid
Use Cases:
- Health checks
- Configuration validation
- Startup verification
mergeResolvers(resolverServices: ResolverService[]): ResolverMap
Combines multiple resolver services into a single resolver map.
Parameters:
resolverServices: ResolverService[]- Array of resolver services
Returns: ResolverMap - Combined resolver map
Features:
- Detects and warns about resolver conflicts
- Continues processing if individual services fail
- Provides detailed error logging
Private Methods
loadSchemaFile(): Promise<string>
Loads GraphQL schema from configured file path.
Returns: Promise<string> - GraphQL schema definition
Error Handling:
ENOENTerrors converted to "Schema file not found"- Empty file detection
- Detailed error messages
validateNeo4jConnection(): Promise<void>
Validates Neo4j database connectivity.
Process:
- Creates database session
- Executes test query (
RETURN 1) - Closes session properly
Throws:
Error- If connection fails or query fails
GqlHealthService
Overview
Health monitoring service for GraphQL system components.
Constructor
constructor(
private readonly schemaService: SchemaService,
@Inject('NEO4J_DRIVER') private readonly neo4jDriver: any
)
Methods
getHealthStatus(): Promise<HealthStatus>
Performs a health check of all system components.
Returns: Promise<HealthStatus> - Detailed health status
Health Checks:
- Neo4j Connection: Tests database connectivity and query execution
- Schema Validation: Validates GraphQL schema compilation
- Service Availability: Checks service registration
Status Levels:
healthy- All systems operationaldegraded- Some non-critical issues detectedunhealthy- Critical systems failing
isHealthy(): Promise<boolean>
Simple boolean health check for load balancers and monitoring.
Returns: Promise<boolean> - True if system is healthy
Use Cases:
- Load balancer health checks
- Kubernetes liveness probes
- Simple monitoring alerts
Health Status Interface
interface HealthStatus {
status: 'healthy' | 'unhealthy' | 'degraded';
timestamp: string;
details: {
neo4j: 'connected' | 'disconnected' | 'error';
schema: 'valid' | 'invalid' | 'error';
services: string[];
};
errors?: string[];
}
Type Interfaces
ResolverService
Interface that all custom resolver services must implement.
interface ResolverService {
getResolvers(): ResolverMap;
}
Implementation Example:
@Injectable()
export class MyResolverService implements ResolverService {
getResolvers(): ResolverMap {
return {
MyType: {
myField: async (parent, args, context) => {
// Resolver logic
return result;
}
}
};
}
}
ResolverMap
Structure for organizing GraphQL field resolvers by type.
interface ResolverMap {
[typeName: string]: {
[fieldName: string]: ResolverFunction;
};
}
Example:
const resolvers: ResolverMap = {
User: {
fullName: (user) => `${user.firstName} ${user.lastName}`,
posts: (user, args, { driver }) => {
// Database query logic
}
},
Post: {
author: (post, args, { driver }) => {
// Fetch author from database
}
}
};
GraphQLContext
Context object available in all GraphQL resolvers.
interface GraphQLContext {
token?: string; // JWT token from Authorization header
driver: any; // Neo4j driver instance
user?: any; // Decoded user information (if authenticated)
}
Usage in Resolvers:
const resolver = async (parent, args, context: GraphQLContext) => {
const { token, driver, user } = context;
if (!user) {
throw new Error('Authentication required');
}
const session = driver.session();
// Use session for database operations
await session.close();
};
ResolverFunction
Type definition for GraphQL resolver functions.
interface ResolverFunction {
(
parent: any, // Parent object (from parent resolver)
args: any, // GraphQL field arguments
context: GraphQLContext, // Request context
info: any // GraphQL execution info
): any; // Return value (can be Promise)
}
Error Types
Schema Errors
- Schema File Not Found:
Schema file not found: {path} - Empty Schema:
Schema file is empty - Parse Error:
Failed to load schema file: {error}
Connection Errors
- Neo4j Connection:
Neo4j connection failed: {error} - Database Query:
Neo4j query execution failed: {error}
Resolver Errors
- Service Error:
Failed to merge resolvers from service: {service} - Conflict Warning:
Resolver conflicts detected for {type}: {fields}
Configuration Errors
- Validation Error:
GraphQL configuration validation failed: {errors} - Missing Environment:
Required environment variable not set: {variable}
Security Features
Query Protection
// Depth limiting prevents deeply nested queries
const depthRule = depthLimit(10);
// Complexity limiting prevents expensive operations
const complexityRule = createComplexityLimitRule(1000);
Authentication Integration
// OIDC JWT validation
authorization: {
key: {
url: process.env.OIDC_JWKS_URI
}
}
Error Sanitization
// Production error formatting (gql.module.ts)
formatError: (error, original) => {
if (process.env.NODE_ENV === 'production') {
return {
message: 'Internal server error',
// The code is the only field that survives, so it is classified rather
// than copied — see src/gql/utils/masked-error-code.ts.
extensions: { code: maskedErrorCode(original ?? error, error.extensions?.code || 'INTERNAL_ERROR') }
};
}
return error; // Full details in development
}
maskedErrorCode() (src/gql/utils/masked-error-code.ts, shared with the SSE transport's sse-error-masking.ts) keeps a code the error already carries, and names the @neo4j/graphql library's own refusals — which carry none, so Apollo would label them INTERNAL_SERVER_ERROR — UNAUTHENTICATED (the @authentication check, and Neo4jGraphQLAuthenticationError) or FORBIDDEN (Neo4jGraphQLForbiddenError). Without it a deployment refusing a validated-but-unlisted caller (DEPLOYMENT_ALLOWLIST) answered exactly as a crash. A real crash still answers INTERNAL_SERVER_ERROR; an error with no code at all answers INTERNAL_ERROR.
Context Security
// Automatic token extraction and validation
context: ({ req, connection }): GraphQLContext => {
return {
token: req.headers?.authorization?.replace('Bearer ', ''),
driver: neo4jDriver,
// User populated by authentication middleware
};
}