Skip to content

Conversation

ruudk
Copy link
Collaborator

@ruudk ruudk commented Oct 3, 2025

This allows the Interface or Union type resolver to modify the object value.

This is useful when you have a single entity that needs different representations. For example, when your data layer returns a generic PetEntity with a type discriminator, but your GraphQL schema has separate Dog and Cat types.

Example:

$PetType = new InterfaceType([
    'name' => 'Pet',
    'resolveType' => static function (PetEntity &$objectValue): string {
        if ($objectValue->type === 'dog') {
            $objectValue = new Dog($objectValue->name, $objectValue->woofs);
            return 'Dog';
        }

        $objectValue = new Cat($objectValue->name, $objectValue->meows);
        return 'Cat';
    },
    'fields' => ['name' => ['type' => Type::string()]],
]);

Now field resolvers receive the properly typed Dog or Cat object instead of the generic PetEntity,
allowing for type-safe resolution without needing to transform objects before they reach the type
resolver.

Common use cases:

  • Database polymorphism (single table with type column)
  • External APIs returning generic objects with type discriminators

Important

Unfortunately, this breaks the InterfaceType and UnionType contract. So this can only be done in a new major
But this serves as a RFC. Maybe there is a better non-breaking way to do this.

/cc @spawnia @simPod

This allows the Interface or Union type resolver to modify the object value.

This is useful when you have a single entity that needs different representations. For example, when
your data layer returns a generic `PetEntity` with a type discriminator, but your GraphQL schema has
separate `Dog` and `Cat` types.

Example:

```php
$PetType = new InterfaceType([
    'name' => 'Pet',
    'resolveType' => static function (PetEntity &$objectValue): string {
        if ($objectValue->type === 'dog') {
            $objectValue = new Dog($objectValue->name, $objectValue->woofs);
            return 'Dog';
        }

        $objectValue = new Cat($objectValue->name, $objectValue->meows);
        return 'Cat';
    },
    'fields' => ['name' => ['type' => Type::string()]],
]);
```

Now field resolvers receive the properly typed Dog or Cat object instead of the generic PetEntity,
allowing for type-safe resolution without needing to transform objects before they reach the type
resolver.

Common use cases:
- Database polymorphism (single table with type column)
- External APIs returning generic objects with type discriminators
- Event sourcing where a single event entity becomes different aggregate types
@ruudk
Copy link
Collaborator Author

ruudk commented Oct 3, 2025

I think this is a better solution to the problem:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant