Skip to main content
Version: 8.0.0

Extending an input type

Available in GraphQLite 4.0+
If you are not familiar with the #[Factory] tag, read first the "input types" guide.

Fields exposed in a GraphQL input type do not need to be all part of the factory method.

Just like with output type (that can be extended using the ExtendType attribute), you can extend/modify an input type using the #[Decorate] attribute.

Use the #[Decorate] attribute to add additional fields to an input type that is already declared by a #[Factory] attribute, or to modify the returned object.

The #[Decorate] attribute is very useful in scenarios where you cannot touch the #[Factory] method. This can happen if the #[Factory] method is defined in a third-party library or if the #[Factory] method is part of auto-generated code.

Let's assume you have a Filter class used as an input type. You most certainly have a #[Factory] to create the input type.

class MyFactory
{
#[Factory]
public function createFilter(string $name): Filter
{
// Let's assume you have a flexible 'Filter' class that can accept any kind of filter
$filter = new Filter();
$filter->addFilter('name', $name);
return $filter;
}
}

Assuming you cannot modify the code of this factory, you can still modify the GraphQL input type generated by adding a "decorator" around the factory.

class MyDecorator
{
#[Decorate(inputTypeName: "FilterInput")]
public function addTypeFilter(Filter $filter, string $type): Filter
{
$filter->addFilter('type', $type);
return $filter;
}
}

In the example above, the "Filter" input type is modified. We add an additional "type" field to the input type.

A few things to notice:

  • The decorator takes the object generated by the factory as first argument
  • The decorator MUST return an object of the same type (or a sub-type)
  • The decorator CAN contain additional parameters. They will be added to the fields of the GraphQL input type.
  • The #[Decorate] attribute must contain a inputTypeName attribute that contains the name of the GraphQL input type that is decorated. If you did not specify this name in the #[Factory] attribute, this is by default the name of the PHP class + "Input" (for instance: "Filter" => "FilterInput")
Heads up! The MyDecorator class must exist in the container of your application and the container identifier MUST be the fully qualified class name.

If you are using the Symfony bundle (or a framework with autowiring like Laravel), this is usually not an issue as the container will automatically create the controller entry if you do not explicitly declare it.