- Configuring your schema
- Add a basic type to the schema configuration
- Activating the default server
- Open up the default server that comes pre-configured with the module
- Building the schema
- Turn your schema configuration into executable code
- Building a schema with procedural code
- Use PHP code to build your schema
Configuring your schema
GraphQL is a strongly-typed API layer, so having a schema behind it is essential. Simply put:
- A schema consists of types
- Types consist of fields
- Fields can have arguments.
- Fields need to resolve
Queries are just fields on a type called "query". They can take arguments, and they must resolve.
There's a bit more to it than that, and if you want to learn more about GraphQL, you can read the full documentation, but for now, these three concepts will serve almost all of your needs to get started.
To start your first schema, open a new configuration file. Let's call it
SilverStripe\GraphQL\Schema\Schema: schemas: # your schemas here
Let's populate a schema that is pre-configured for us out of the box,
SilverStripe\GraphQL\Schema\Schema: schemas: default: config: # general schema config here types: # your generic types here models: # your dataobjects here queries: # your queries here mutations: # your mutations here
Avoid config flushes
Because the schema YAML is only consumed at build time and never used at runtime, it doesn't
make much sense to store it in the configuration layer, because it just means you'll
flush=1 every time you make a schema update, which will slow down your builds.
It is recommended that you store your schema YAML outside of the _config directory to increase performance and remove the need for flushing.
We can do this by adding a
src key to our schema definition that maps to a directory
relative to the project root.
SilverStripe\GraphQL\Schema\Schema: schemas: default: src: app/_graphql
SilverStripe\GraphQL\Schema\Schema: schemas: default: src: - app/_graphql - module/_graphql
Now, in our
app/_graphql file, we can create YAML file definitions.
srcattribute, those are still a standard config changes.
# no schema key needed. it's implied! config: # your schema config here types: # your generic types here models: # your dataobjects here queries: # your queries here mutations: # your mutations here
Namespacing your schema files
Your schema YAML file will get quite bloated if it's just used as a monolithic source of truth
like this. We can tidy this up quite a bit by simply placing the files in directories that map
to the keys they populate -- e.g.
There are two approaches to namespacing:
- By filename
- By directory name
Namespacing by directory name
If you use a parent directory name (at any depth) of one of the four keywords above, it will be implicitly placed in the corresponding section of the schema.
# my schema config here
# my type definitions here
# my type definitions here
Namespacing by filename
If the filename is named one of the four keywords above, it will be implicitly placed in the corresponding section of the schema. This only works in the root source directory.
# my types here
# my models here
Going even more granular
These special directories can contain multiple files that will all merge together, so you can even create one file per type, or some other convention. All that matters is that the parent directory name matches one of the schema keys.
The following are perfectly valid:
In addition to all the keys mentioned above, each schema can declare a generic
config. This are mostly used for assigning or removing plugins
An important subsection of
modelConfig, where you can configure settings for specific
Like the other sections, it can have its own
config.yml, or just be added as a
mapping to a generic schema yaml document.
modelConfig: DataObject: plugins: inheritance: true operations: read: plugins: readVersion: false paginateList: false
Defining a basic type
Let's define a generic type for our GraphQL schema.
Country: fields: name: String code: String population: Int languages: '[String]'
To define a type as a list, you wrap it in brackets:
To define a type as required (non-null), you add an exclamation mark:
Often times, you may want to do both: