#[SourceField] implies usage of getter methods
Hello!
Don't know if I overlooked a thing: I have a value object that I want to expose via type. Value object is rather simple:
class Value {
public function __construct() {
public readonly int $something;
}
}
And my type:
#[SourceField('something')]
class ValueType {
}
And then I get: There is an issue with a @SourceField annotation in class …: Could not find a getter or a isser for field.
Is this an intentional thing or missing feature? From what I checked against the codebase, there's no support for reading properties directly. But may be I am holding it wrong.
It would be nice not to have getters in type just to work around it.
#[Type]
class Value {
public function __construct() {
#[Field]
public readonly int $something;
}
}
?
This is why I’m against having too many attributes. They’re confusing for people.
@oprypkhantc how about not polluting Domain with attributes? @oojacoboo uhm, I'm talking about something different: just to have support for properties as SourceField directly. Especially we have properties with get/set visibility modifiers slowly adopting.
@er1z If your GQL representation equals your domain (which is what it seems you're trying to do), then there's no point in separating the attributes from the rest of the code, if they match 1-1 anyway. Attributes in PHP and annotations in other languages were always designed to "pollute" the code in such a way that doesn't affect it.
If, on the other hand, your domain and representation are separate, and you're mapping your domain entities to their representations, then you can use plain old #[Type] + #[Field] if you're mapping all properties, or #[Type] + #[MagicField] + __call/__get if you're wrapping them.
A third option (probably what you're looking for) is this: https://github.com/thecodingmachine/graphqlite/blob/master/tests/Fixtures/TestSourceNameType.php#L14 https://graphqlite.thecodingmachine.io/docs/external-type-declaration
But I really see no point in doing that if you control the class.
We are also in the process of expanding the approach to utilize public readonly properties for our DTOs and want to separate our GraphQL staff from our internal staff.
For now, we're using the way like below, but it's not so comfortable for us:
#[Type(class: Product::class)]
class ProductType
{
#[Field]
public function getId(Product $product): string
{
return $product->id;
}
#[Field]
public function getTitle(Product $product): string
{
return $product->title;
}
}
I see that graphqlite can work with properties as a source of data, but it is limited to using magic properties fetched via __get method, not directly
@andrew-demb we have Types that have Fields defined on properties. What's the issue you're having? A getter is optional and not required.
@oojacoboo the same as author - we want to use separated class for graphql bindings with SourceField attributes and public properties with no getters in source DTO.
Ideally, I want to use such code:
readonly class Product
{
public function __construct(public string $id, public string $title) {}
}
#[Type(class: Product::class)]
#[SourceField(field: "id")
#[SourceField(field: "title")
class ProductType
{
}
This is what I exactly meant filling this ticket! May be would be beneficial to use PropertyAccessor from Symfony components to get the value of the field as current value determine process is rather restricted.
Well, a PR that allows SourceField to target public properties is welcomed.
I will say, we started down the path of keeping our domain and GraphQL logic separated out, then realized the class duplication actually made a mess and wasn't really solving much. And since attributes are metadata, it's not like they're actually polluting the domain, certainly not anymore than Doctrine attributes or others.