graphql-platform icon indicating copy to clipboard operation
graphql-platform copied to clipboard

Infer FilterInputType from defined ObjectType

Open lucasneuwit opened this issue 1 year ago • 2 comments

Product

Hot Chocolate

Is your feature request related to a problem?

I'm facing unexpected behavior when defining my GraphQL types. We are using the code-first approach with explicit field-binding behavior so we do not accidentally expose fields to our schema.


public class User
{
    public string LoginId { get; set; }

    public string DisplayName { get; set; }

    public string Password { get; set; }
}

public class UserType : ObjectType<User>
{
    protected override void Configure(IObjectTypeDescriptor<User> descriptor)
    {
        base.Configure(descriptor);
        descriptor.BindFieldsExplicitly();
        descriptor.Field(x => x.DisplayName);
        descriptor.Field(x => x.LoginId);
    }
}

We later call UseFiltering() in our resolver for this type, expecting that the available fields for filtering would follow the fields exposed for selection (in short, should not be able to filter by an user's password if the field is already not being exposed). Yet, this does not seem to be achievable without specifying an explicit FilterInputType for the User type

public class UserFilterInputType : FilterInputType<User>
{
    protected override void Configure(IFilterInputTypeDescriptor<User> descriptor)
    {
        base.Configure(descriptor);
        descriptor.BindFieldsExplicitly();
        descriptor.Field(x => x.DisplayName);
        descriptor.Field(x => x.LoginId);
    }
}

This doesn't look like a problem at first glance but as our schema grows (both in number of types being exposed and number of fields for each type) we will end up with lots of duplicate code by having to explicitly define each field at least twice.

Nevertheless, the way we expect this to work is accomplished by using the annotation-based approach, since

public class User
{
    public string LoginId { get; set; }

    public string DisplayName { get; set; }

    [GraphQLIgnore]
    public string Password { get; set; }
}

does exclude the field both from the selection set and the filter type with no need to configure each schema type separately.

The solution you'd like

The implicitly defined FilterInputType<T> that is generated when calling UseFiltering() on a type that already has been configured by an ObjectType<T> should only consider fields defined in the type configuration when using explicit field-binding behavior in the code-first approach, similar to how annotation-based approach handles exposed and ignored fields.

lucasneuwit avatar Jun 13 '24 23:06 lucasneuwit

It looks we're after a similar solution https://github.com/ChilliCream/graphql-platform/issues/6314

PHILLIPS71 avatar Sep 04 '24 10:09 PHILLIPS71

This is not as easy as you think ... an object type only in the simplest of cases aligns with the filter type ... there are so many edge cases here that would make such an inference pretty random.

michaelstaib avatar Sep 04 '24 16:09 michaelstaib