ChilliCream / ChilliCream/graphql-platform

Add filtering convention runtime type binding support for open generic types

Open
#7,082 1 comment 3 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

🌶️ hot chocolate Area: Data
Dominant language
C#
Stars
5.8k
Forks
810
Avg merge
15h 39m
Merged PRs (30d)
98

Description

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.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at IFilterConventionDescriptor.BindRuntimeType and reproduce the open-generic example with Id<> and IdFilterType<>. Compare the generated filter input with the expected comparable input, including the custom scalar case. Done means open generic bindings or registered custom scalars produce the appropriate filtering input without manual per-type registrations.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
api, backend
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.