Computed Fields

You may add any computed field to an entity definition. This is done with the EntityDefinition Event.

Modify an Entity Definition

You may modify the array used to define an entity type before it is created. This can be used for computed data. You must attach a listener before defining your GraphQL schema.

Events of this type are named Entity::class . '.definition' and the event name cannot be modified.

use ApiSkeletons\Doctrine\ORM\GraphQL\Driver;
use ApiSkeletons\Doctrine\ORM\GraphQL\Event\EntityDefinition;
use App\ORM\Entity\Artist;
use App\ORM\Entity\Performance;
use Doctrine\ORM\EntityManager;
use GraphQL\Type\Definition\ResolveInfo;
use League\Event\EventDispatcher;

$driver = new Driver($entityManager);

$driver->get(EventDispatcher::class)->subscribeTo(
    Artist::class . '.definition',
    static function (EntityDefinition $event) use ($driver): void {
        $definition = $event->getDefinition();

        // In order to modify the fields you must resolve the closure
        $fields = $definition['fields']();

        /**
         * Add a computed field to show the count of performances
         * This field will only be computed when it is requested specifically
         * in the query
         */
        $fields['performanceCount'] = [
            'type' => Type::int(),
            'description' => 'The count of performances for an Artist',
            'resolve' => static function (Artist $objectValue, array $args, $context, ResolveInfo $info) use ($driver): int {
                $queryBuilder = $driver->get(EntityManager::class)->createQueryBuilder();
                $queryBuilder
                   ->select('COUNT(performance)')
                   ->from(Performance::class, 'performance')
                   ->andWhere($queryBuilder->expr('performance.artist', ':artistId'))
                   ->setParameter('artistId', $objectValue->getId());

                return $queryBuilder->getQuery()->getScalarResult();
            },
        ];

        // Assign modified fields array to the ArrayObject
        $definition['fields'] = $fields;
    }
);

A query for this computed field:

query ArtistQueryWithComputedField($id: Int!)  {
  artist(id: $id) {
    id
    name
    performanceCount
  }
}

This is documentation for API-Skeletons/doctrine-orm-graphql. Please add your ★ star to the project.

Authored by API Skeletons.