What is a Central Schema?
Viaduct serves a central schema: a single, integrated GraphQL schema connecting all domains across your organization. While this schema is developed in a decentralized manner by many teams, it presents as one highly connected graph to clients.The central schema is the complete, unified GraphQL schema that results from merging all tenant module schemas together. It represents the full graph of your organization’s data and capabilities.
Key Principles
Single Graph
One unified schema connecting all domains, not a collection of separate schemas
Decentralized Development
Multiple teams independently contribute types and fields to the central schema
Type Extensions
Teams can extend types owned by other teams without direct code dependencies
Schema Composition
All team schemas are merged at build time into the central schema
How Teams Contribute
Teams contribute to the central schema through tenant modules. Each module contains:- GraphQL SDL files defining types, queries, mutations
- Resolvers implementing the business logic for those fields
- Independence from other modules’ code
Example: Two Teams Collaborating
Let’s look at how two teams contribute to aUser type:
The Messaging team’s resolvers can access
firstName and lastName through GraphQL fragments without depending on the Core User team’s code.Schema Composition Process
Viaduct merges tenant schemas at build time through a multi-step process:Module Dependencies
Modules form a dependency graph that determines composition order:- Building
presentation/checkoutincludes:presentation,data,entity,entity/common - Building
entity/userincludes:entity,entity/common
Real-World Example: Star Wars Demo
The Star Wars demo application demonstrates central schema composition with two modules:Universe Module
Defines core Star Wars entities:modules/universe/src/main/viaduct/schema/Planet.graphqls
Filmography Module
Extends entities with film-related fields:modules/filmography/src/main/viaduct/schema/Character.graphqls
Notice how the
Character type references Planet and Species from the universe module. The central schema makes these cross-module relationships seamless.Common Types and Shared Modules
For types used across multiple tenants, create a common module:modules/common/schema/CommonTypes.graphqls
common can reference these types:
Schema Variants with Scopes
The central schema can expose different variants using scopes. All tenants contribute to the same central schema, but fields can be marked with different scopes:Registering Schema Variants
Service engineers configure which scopes map to which schema IDs:Benefits of a Central Schema
For Developers
One Graph
Query across domains in a single request without orchestrating multiple services
Type Safety
Strong typing across module boundaries with generated code
No Duplication
Shared types prevent duplicate definitions across teams
Discovery
Browse the entire graph through introspection
For Organizations
- Faster Development: Teams extend existing types instead of creating new APIs
- Better Client Experience: Single endpoint for all data needs
- Reduced Coordination: Teams work independently on their schema portions
- Consistent Data Model: One source of truth for your domain model
Schema Governance
With a central schema, consider these governance practices:Naming Conventions
Establish consistent naming for types and fields:Field Ownership
Clearly document which team owns each type:Breaking Change Prevention
Schema Reviews
Implement review processes for schema changes:- Automated validation: Check for breaking changes in CI
- Type ownership: Require approval from owning team for extensions
- Naming review: Ensure consistency with existing conventions
Compilation Schemas
While Viaduct maintains a central schema, each tenant module only generates code for the types it actually uses:A compilation schema is a per-tenant-module, private view of the central schema consisting of only the schema elements that module uses.
- Keeps build times fast even with a large central schema
- Enables parallel builds of tenant modules
- Only rebuilds when a module’s dependencies change
- Central schema has 500 types
filmography/charactersmodule only uses 20 types- Only those 20 types (and their dependencies) are in the compilation schema
- Generated code is minimal and builds quickly
Troubleshooting
Type Not Found Errors
If you get “unresolved reference” errors for a type:- Ensure the module defining that type is in your dependencies
- Check that schema files are in the correct location:
src/main/viaduct/schema/ - Verify the type is included in your scope configuration
Duplicate Type Definitions
If you see “type already defined” errors:- Use
extend typeinstead of redefining the type - Check that only one module defines the base type
- Review module dependencies to ensure proper composition order
Schema Composition Failures
If schema validation fails after composition:- Run introspection queries to examine the composed schema
- Check for conflicting field definitions on extended types
- Ensure all referenced types are defined or extended with proper scopes
See Also
- Tenant Modules - Building modular applications with isolated schemas
- Re-entrancy - How modules compose through GraphQL fragments
- Architecture - Understanding the three-layer design