Reusable GraphQL schema elements concept for IBM API Connect for GraphQL/StepZen.
Note
IBM API Connect for GraphQL was originally StepZen, this document uses StepZen for brevity.
A StepZen GraphQL schema can be composed from a combination of existing reusable schema elements. This lays out a convention based approach of how reusable schemas should be defined as schema atoms.
The goal is to encourage a plug-and-play approach avoiding dependencies between unrelated schema atoms.
For example in this project's package delivery scenario we have:
- an interface based package delivery schema that allows BFF schemas to hide implementation details from clients
- multiple instances of delivery service schemas that can provide the implementations of the interface (e.g. Fast Package , RainOrShine , Mercury )
A reusable schema approach allows any of these combinations to be created and deployed:
- interface delivery service with mocking only
- interface delivery service with only a Fast Package implementation
- interface delivery service with any combination of Fast Package, RainOrShine, ... implementations
- Fast Package only service
- etc.
Thus for example, it should be possible to deploy Fast Package service without including the delivery interfaces.
Schema atoms also encourage a unit testing approach since a schema atom can be deployed independently.
A deployable schema is a schema that can be deployed to a running service using stepzen deploy
resulting in a live endpoint.
A deployable schema is represented in a project as a top-level folder containing:
- at least one
index.graphql
containing GraphQL schema definitions (using SDL)- Multiple
.graphql
files are included through@sdl
directive - Sub-folders may be used to organize multiple
.graphql
files - Files included through
@sdl(files:)
byindex.graphql
can further include files by using@sdl
on anextend schema
clause. - Relative paths for the
@sdl(files:)
argument are relative to the file containing the.graphql
file with@sdl
and are restricted to sub-folders (e.g.customer/types.graphql
,customer/database/types.graphql
but not../types.graphql
)
- Multiple
- a
stepzen.config.json
configuration file defining the endpoint name - an optional
config.yaml
configuration file containing configuration and access rules
A deployable schema may be comprised of:
- (preferred) one or more schema atoms included through their
atom.graphql
files using@sdl
. .graphql
files that are not organized into a schema atom included through@sdl
including arbitrary nesting.- a combination of the above.
Note
This is a convention to encourage resuablilty of schema elements and an engineering disipline to GraphQL schema development.
A schema atom is a reuseable collection of GraphQL schema definitions.
A schema atom is a folder containing:
atom.graphql
- This is the single file that allows the schema atom to be included in deployable schemas or other schema atoms through@sdl
, e.g.@sdl(files:["fast-package/core/atom.graphql"])
.- Optional additional
.graphql
files included through@sdl(files:)
, with the root beingatom.graphql
.
Schema atoms can take advantage of GraphQL extend
definitions, for example, to add fields to types (especially Query
), or enum values to an enum.
Note
A schema atom can be a "molecule", made up from multiple schema atoms but still a reusable set of schema elements. For example a goespatial schema atom that depends on geolocation and weather services schema atoms. In this case the result is still termed a schema atom, as the usage is the same as a self-contained schema atom.
As index.graphql
represents the root of a deployable schema it should include a schema definition with a description
of the schema or endpoint (which is then available through introspection).
"""
Customer endpoint provides access to customer information including orders.
"""
schema {
query: Query
mutation: Mutation
}
Several related schema atoms may exist, a convention would be have three "type" folders under the root folder:
core
- core definitions, typically a single schema atom, but potentially multiple, e.g.fast-package/core/status
,fast-package/core/mgmt
etc.extend
- any schema atom that expand the functionality of other schema atom definitions, e.g.fast-package/extend/delivery
mock
- schema atom that mock types within core definitions for testing, etc. Typically one, but potentially multiple.
atom.graphql
should contain a schema definition extension (extend schema
) that includes the .graphql
files that implement the atom.
- Example:
fast-package/core/atom.graphql
.
Simple schema atoms could have their definitions contained completely in atom.graphql
.
- Example:
fast-package/mock/atom.graphql
.
Schemas may be developed by different groups, different organizations including open source.
Thus while a deployment schema S
may require multiple schema atoms (A,B,C
) it cannot be assumed that the source
for all the included atoms is located in sub-folders of the repository folder for S
.
Thus a process is needed where the source folders for A,B,C
must be copied into a folder that contains S
before the schema is deployed,
typically by a CI-CD process e.g. a github workflow. This could be either:
- Copying
S,A,B,C
into a temporary folder and deploying from there - Copying
A,B,C
into the folder forS
and deploying from that folder
Note @sdl(files:)
does not support relative paths going above the current folder (e.g. ../weather/atom.graphql
is not supported).
endpoints/delivery
- deployment of schema atom with only interface types, thus the interface types are mocked since there are no implementations.endpoints/fast-package
- deployment of a single schema atomendpoints/fast-package-mock
- deployment of a core schema with its mock schema atom
delivery/core
- interface for a delivery service applicationfast-package/core
- Fast Package core functionality (simulating a call to a REST service)fast-package/mock
- Allowsfast-package/core
to be mocked to avoid real calls during application testing.fast-package/extend/delivery
- Extendsfast-package/core
to implementdelivery/core