Version 5
supported
Extending the schema
- Adding a custom operation
- Add a new operation for model types
- The global schema
- How to push modifications to every schema in the project
- Adding middleware
- Add middleware to to extend query execution
- Adding a custom model
- Add a new class-backed type beyond DataObject
Adding a custom operation
By default, we get basic operations for our models, like read
, create
,
update
, and delete
, but we can add to this list by creating
an implementation of OperationProvider
and registering it.
Let's build a new operation that duplicates DataObjects.
class DuplicateCreator implements OperationCreator
{
public function createOperation(
SchemaModelInterface $model,
string $typeName,
array $config = []
): ?ModelOperation
{
$mutationName = 'duplicate' . ucfirst(Schema::pluralise($typeName));
return ModelMutation::create($model, $mutationName)
->setType($typeName)
->addArg('id', 'ID!')
->setDefaultResolver([static::class, 'resolve'])
->setResolverContext([
'dataClass' => $model->getSourceClass(),
]);
}
}
We add resolver context to the mutation because we need to know what class to duplicate, but we need to make sure we still have a static function.
The signature for resolvers with context is:
public static function (array $context): Closure
We use the context to pass to a function that we'll create dynamically. Let's add that now.
public static function resolve(array $resolverContext = []): Closure
{
$dataClass = $resolverContext['dataClass'] ?? null;
return function ($obj, array $args) use ($dataClass) {
if (!$dataClass) {
return null;
}
return DataObject::get_by_id($dataClass, $args['id'])
->duplicate();
};
}
Now, just add the operation to the DataObjectModel
configuration
to make it available to all DataObject
types.
app/_graphql/config.yml
modelConfig:
DataObject:
operations:
duplicate:
class: 'MyProject\Operations\DuplicateCreator'
And use it:
app/_graphql/models.yml
MyProject\Models\MyDataObject:
fields: '*'
operations:
read: true
duplicate: true