A walk in GraphQL — Extending SDL definitions — Day 6
8 articles to learn GraphQL incrementally, keeping the implementation agnostic spirit of the SDL

Extend
The extend
keyword in SDL provides the ability to add properties to existing SDL definitions.
What kind of definitions can you extend and what can you add to them?
Syntax summary from the GraphQL spec
GraphQL spec — June 2018 — B.3 Document
SchemaExtensionextend
schema
Directives { OperationTypeDefinitions }extend
schema
Directives
ScalarTypeExtensionextend
scalar
Name Directives
ObjectTypeExtensionextend
type
Name ImplementsInterfaces Directives FieldsDefinitionsextend
type
Name ImplementsInterfaces Directivesextend
type
Name ImplementsInterfaces
InterfaceTypeExtensionextend
interface
Name Directives FieldsDefinitionsextend
interface
Name Directives
UnionTypeExtensionextend
union
Name Directives UnionMemberTypesextend
union
Name Directives
EnumTypeExtensionextend
enum
Name Directives EnumValuesDefinitionsextend
enum
Name Directives
InputObjectTypeExtensionextend
input
Name Directives InputFieldsDefinitionextend
input
Name Directives
Does it mean we can extend pretty much everything declared in an existing schema?
Yup
With great power comes great responsibility 🕸
Clearly this has specific rules:
- What you are extending must be already declared.
- Anything you add must not already apply to the original definition.
And comes at a great cost:
- As opposite to what
extend
concept implies for other languages, in SLD there’s no place for inheritance, subclassing, etc., you’re actually extending the original thing … by modifying it. E.g. you cannot do something liketype MyType extends MyOtherType
, you justextend type MyType
and now the originalMyType
has been modified with the new thing you added to it. - Again,
extend
is a modifier.
What’s the use?
Now that we know the syntax, the rules and the cost … gimme the benefits dude!!!!
You may say: — hey! I could use extend
instead of dealing with interface
complexity
— well, sort of, if you don’t want the implementation contract of the interface, but maybe you didn’t want an interface
at all from the beginning.
— hey! I may extend the Operation Type Definitions in order to organize it more clearly on my file adding the queries, mutations and subscriptions close to the related Object Types they’re dealing with!
— Now we’re on the good track!!!
Let’s go back to our previous example:
A pretty simple file with a simple domain complexity, still, if we start organizing it differently it’s gonna be easier to understand.
An underlying pattern is becoming evident, we have at least two potential domains, right?, now imagine if Sword
, Realm
, City
types are added … and this is still a ridiculously small app!!! and as a seasoned engineer you might want to separate them into specific files, maybe in specific directories and so on; well, here’s where things become complicated.
Scaling your Schema
There’s so much to say about this argument, and the considerations will vary depending on the prerequisites and circumstances, e.g. the project type (personal, enterprise, experimental), the scale (single person, small team, multiple teams, distributed teams) and many other! So in a high level overview we’ll mention some of those considerations and leave you the links to the most valuable documents I’ve seen so far which represent the best practices determined by the industry after years of designing GraphQL at scale. One of the most relevant documents is the “Principled GraphQL”, written by Geoff Schmidt and Matt DeBergalis, which we’ll mention several times in this chapter, but it’s not the only one as many great engineers are sharing with all of us their invaluable experience.
Graph Breakdown
One of the first things that will hit you is the “One Graph” principle which by any means is referred to have one single file; it means that you have to have a single source of truth (one unified graph) that represents the interactions between the actors and the data through Aggregates (Objects & Relationships), Views (Queries) and Commands (Mutations); here is where we have 2 primary options, the Monolithic architecture (e.g. Schema Stitching), and the Federated architecture, (e.g. Apollo Federation). Other options like graphql-modules combine the declaration and execution code all together but we won’t describe it here. While the former is considered deprecated or not recommended for many reasons we’ll see later, we still encourage you to know it and practice it because:
- It’s still applies to small project
- You’ll still find it alive and kicking in many projects
- The migration from schema stitching to federation is thoroughly documented, and you may consider this process the natural evolution of small or legacy projects when the need for scale arise.
Clearly this discussion is around architecture and not about GraphQL explicitly, therefore the actual implementation will depend on the technology. We’ll see the concept as detached from the technologies as possible but when a particular example will require it, we’ll use Apollo’s related technologies as it’s leading the trend for now.
Here some of the most evident differences between Schema Stitching and Apollo Federation

Another summarized high level description we like can be read in GraphQL Federation vs Stitching by Gunar Gessner.
All above is only achievable thanks to extend
, a simple keyword on the spec is the door that opens towards hell or heaven depending on how you use it.
Schema Stitching example
In order to keep the learning path more natural and start with the simplest example we will go for the Stitching technique for now and dedicate a whole day for Federation in the future.
SDL
So how our example would look like if we use the stitching technique?
schema.gql
character.gql
magicalCreature.gql
Resolvers
And the resolvers?
Well, you might separate them into specific files too or keep them in one place, again, that’s an engineering concern and will depend on the technology, GraphQL just doesn’t care, granted they’re passed along with the type definitions to the server.
Server
See here how our implementation might look like using Apollo Server in an oversimplified example.
When things go wrong (︶︹︶)
a.k.a. how to resolve conflicts
So far our example worked smoothly just because we were moving a working SDL document to 3 documents, but what happens when the number of documents and lines of code scale and you need to handle fields, types or other conflicts? Clearly just importing the SDL files won’t work anymore. In this case you’ll have to leverage the existing tools available for your technology or eventually write your own if nothing fit your needs.
graphql-tools/merge
You might still find some previous implementations using graphql-tools/mergeSchemas
which has been deprecated in favor of the above mentioned.
See below the migration tutorial and some old documentation as you might still find it in a project.
- Migration from Merge GraphQL Schemas
- Merging Schemas with
graphql-tools/mergeSchemas
— No conflicts
— Conflicts for root fields
— Conflicts for types
— Merging an executable with a non-executable schema
Exercise
For a given datasource (abstracted as json here) containing n
rows of skills
and n
rows of persons
we provided a sample implementation of a GraphQL server for each technology containing:
- a server app
- a schema
- a resolver map
- an entity model
- a db abstraction
The code contains the solution for previous exercises so you can have a starting point example.
Exercise requirements
This exercise might require additional instructions depending on the technology, please read them carefully before starting.
Schema
- Identify and separate the SDL document into 4 documents in a per-type basis
- Here a completely arbitrary example (you can experiment different setups if you want)
— globalSearch.gql
— person.gql
— schema.gql
— skill.gql - Update the server app in order to include and stitch all schemas together
- You can directly import the *.gql files or use a technology specific utility like
apollo-tools
or whatever you want
As you can see, the challenge here will depend on the technology and we encourage you to experiment and try different approaches.
Operations list
All previous operations MUST work regardless the stitching technique implemented.
Technologies
Select the exercise on your preferred technology:
Learning resources
GraphQL Spec (June 2018)
- Type system Extension
- Schema Extensions
- Types Extensions
- Scalar Extensions
- Object Extensions
- Interface Extensions
- Union Extensions
- Enum Extensions
- Input Extensions
Apollo Blog
Apollo GraphQL
graphql-tools
- Schema Delegation
- Remote Schemas
- Schema Wrapping
- Schema Merging
- Type definitions (SDL) merging
- Resolvers merging
- GraphQLSchema merging
- Schema stitching
Advanced GraphQL dot com
Youtube
- GraphQL Schema Design @ Scale by Marc-André Giroux (amazing video)
- Migrating Apollo’s Data Graph from Schema stitching to Federation by Adam Zionts
Other articles
- Principled GraphQL by Geoff Schmidt and Matt DeBergalis
- Domain-Driven GraphQL Schema Design | Enterprise GraphQL by Khalil Stemmler (highly recommended)
- GraphQL Federation vs Stitching by Gunar Gessner
- GraphQL Stitching versus Federation by Sebastiaan Andeweg
- Advice from a GraphQL Expert by Sarah Drasner (and Francesca Guiducci)
- The Guild
- graphql-tools — Schema Stitching
- GraphQL Tools is back — next generation schema stitching and new leadership
- The Guild is taking over maintenance of merge-graphql-schemas
GraphCMS
Ariadne
A walk in GraphQL Series at Medium
- Introduction
- Day 1 — Queries and Resolvers
- Day 2 — Arguments and Variables
- Day 3 — Input Objects and Enums
- Day 4 — Mutations
- Day 5 — Interfaces and Unions
- Day 6 — Extending SLD definitions
- Day 7 — Errors
Github Pages
Collaborators
- Ezequiel Alvarez — @ealvarezk
Reviewer - Ezequiel Tejerina — @quequitejerina
Python exercises contributor and reviewer - Franco Gribaudo — @fgriba
Java exercises contributor and reviewer - Cristian Buffa — @cristianbuffa & José Ignacio Aguilera — @jiaguilera
NetCore exercises contributors and reviewers - Javier Valderrama — @Jaxolotl
Author, JavaScript exercise contributor and reviewer