Getting started

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
You are viewing docs for a pre-release version of silverstripe/graphql (4.x). Help us improve it by joining #graphql on the Community Slack, and report any issues at github.com/silverstripe/silverstripe-graphql. Docs for the current stable version (3.x) can be found here

Building a schema with procedural code

Sometimes you need access to dynamic information to populate your schema. For instance, you may have an enum containing a list of all the languages that are configured for the website. It wouldn't make sense to build this statically. It makes more sense to have a single source of truth.

Internally, model-driven types that conform to the shapes of their models must use procedural code to add fields, create operations, and more, because the entire premise of model-driven types is that they're dynamic. So the procedural API for schemas has to be pretty robust.

Lastly, if you just prefer writing PHP to writing YAML, this is a good option, too.

One thing you cannot do with the procedural API, though it may be tempting, is define resolvers on the fly as closures. Resolvers must be static methods on a class, and are evaluated during the schema build.

Adding executable code

We can use the execute section of the config to add an implementation of SchemaUpdater.

SilverStripe\GraphQL\Schema\Schema:
  schemas:
    default:
      config:
        execute:
          - 'MyProject\MySchema'

Now just implement the SilverStripe\GraphQL\Schema\Interfaces\SchemaUpdater interface.

app/src/MySchema.php

use SilverStripe\GraphQL\Schema\Interfaces\SchemaUpdater;
use SilverStripe\GraphQL\Schema\Schema;

class MySchema implements SchemaUpdater
{
    public static function updateSchema(Schema $schema): void
    {
        // update here
    }
}

Example code

Most the API should be self-documenting, and a good IDE should autocomplete everything you need, but the key methods map directly to their configuration counterparts:

  • types (->addType(Type $type))
  • models (->addModel(ModelType $type))
  • queries (->addQuery(Query $query))
  • mutations (->addMutation(Mutation $mutation))
  • enums (->addEnum(Enum $type))
  • interfaces (->addInterface(InterfaceType $type))
  • unions (->addUnion(UnionType $type))
    public static function updateSchema(Schema $schema): void
    {
        $myType = Type::create('Country')
            ->addField('name', 'String')
            ->addField('code', 'String');
        $schema->addType($myType);

        $myQuery = Query::create('readCountries', '[Country]')
            ->addArg('limit', 'Int');

        $myModel = $schema->createModel(MyDataObject::class)
            ->addAllFields()
            ->addAllOperations();
        $schema->addModel($myModel);

    }

Fluent setters

To make your code chainable, when adding fields and arguments, you can invoke a callback to update it on the fly.

$myType = Type::create('Country')
    ->addField('name', 'String', function (Field $field) {

        // Must be a callable. No inline closures allowed!
        $field->setResolver([MyClass::class, 'myResolver'])
            ->addArg('myArg', 'String!');
    })
    ->addField('code', 'String');
$schema->addType($myType);

$myQuery = Query::create('readCountries', '[Country]')
    ->addArg('limit', 'Int', function (Argument $arg) {
        $arg->setDefaultValue(20);
     });

Further reading

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