Skip to content

Add filtering convention runtime type binding support for open generic types #7082

@Lippur

Description

@Lippur

Product

Hot Chocolate

Is your feature request related to a problem?

The BindRuntimeType method on the IFilterConventionDescriptor does not currently work for open generic types. This means that every generic type definition has to be registered separately. Since the filter convention is configured earlier than all schema types are discovered, automatic registration is also not possible via interceptors or other means.

In practical terms, this means that using custom scalars for generic types in combination with filtering for these custom scalars is not possible and leads to incorrect filter inputs being generated, which also cannot be removed or ignored automatically.

Example

builder.Services.AddGraphQLServer()
// ...
  .AddFiltering(f =>
    {
      f.BindRuntimeType(typeof(Id<>), typeof(IdFilterType<>)); // IdFilterType<T> implements ComparableOperationFilterInputType<T>
    }
  )

This binding is ignored entirely during runtime. Instead of a comparable filter input type, a default object comparison input type is added.

The only way to make it work is to register all types manually:

builder.Services.AddGraphQLServer()
// ...
  .AddFiltering(f =>
    {
      f.BindRuntimeType(typeof(Id<MyEntity>), typeof(IdFilterType<MyEntity>));
      f.BindRuntimeType(typeof(Id<OtherEntity>), typeof(IdFilterType<OtherEntity>));
      // ... and so on
    }
  )

This is extremely non-ergonomic and defeats the entire purpose of generic types in C#.

This problem is made much worse by the fact that filtering completely ignores the bindings of custom scalars. Even if a type uses a custom scalar which is a StringValueNode (ScalarType<Id, StringValueNode> for example), filtering still treats it like an object, not a string. This is documented in the HotChocolate documentation, but that shortcoming makes the issue with generic types even worse.

The solution you'd like

The issue could be solved if any of the following fixes are made to the runtime type binding for filtering:

  1. Allow binding open generic types and/or interfaces which are then correctly resolved at runtime to register the appropriate input objects.
  2. Use the custom scalars already registered in the schema without separately registering them with the filtering convention.
  3. Allow binding custom scalars to filter types directly, rather than having to register the underlying runtime type of the custom scalar, and use the actual schema type of the scalar for filtering, e.g. if the custom scalar is a StringValueNode, treat the value as a string for filtering too.

Ideally, all three should be implemented, but any one of the three would fix this particular issue.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions