0

How can I set up Hot Chocolate filtering to work when a class has a char field?

I have a class with a Status field of type char. Strangely, it seems that Hot Chocolate does not work with char fields. To get it to even generate a schema I had to configure AddGraphQLServer() like this:

builder.BindRuntimeType<char, StringType>()

and then to get queries to work I had to do this:

builder.AddTypeConverter<char, string>(_ => _.ToString())

(I presume I will need AddTypeConverter<string, char> for mutations.)

But filtering does not work. If I add [UseFiltering] to a resolver, I can no longer even generate a schema. The error I get is

The type of the member Status of the declaring type Offer is unknown

What is the simplest way to get filtering to work here? I have read some slightly out-of-date inforamtion about IFilterConvention but haven't been able to get anything working. I hope this very simple thing (which really should work out of the box) will require only a little bit more code.

Bennett McElwee
  • 24,740
  • 6
  • 54
  • 63

1 Answers1

0

It's all a bit awkward, since char is not a first-class GraphQL type. We added converters to convert between char and string, and added a custom filter convention so we could filter by char.

public void ConfigureServices(IServiceCollection services)
{
    services
        // Add our custom conventions for filtering
        .AddConvention<IFilterConvention, CustomFilterConvention>()
        // Add support for char (treat as string)
        .BindRuntimeType<char, StringType>()
        .AddTypeConverter<char, string>(_ => _.ToString())
        .AddTypeConverter<string, char>(_ => _[0])
        // Add support for char? (treat as string)
        .BindRuntimeType<char?, StringType>()
        .AddTypeConverter<char?, string>(_ => _?.ToString() ?? "")
        .AddTypeConverter<string, char?>(_ => _[0])
        // ...etc
}

public class CustomFilterConvention : FilterConvention
{
    protected override void Configure(IFilterConventionDescriptor descriptor)
    {
        base.Configure(descriptor);

        descriptor.BindRuntimeType<char, ComparableOperationFilterInputType<char>>();
        descriptor.BindRuntimeType<char?, ComparableOperationFilterInputType<char?>>();
        descriptor.AddDefaults();
        descriptor.Provider(new QueryableFilterProvider(_ => _.AddDefaultFieldHandlers()));
    }
}

I think a better approach might be to just change our entity class to use string instead of char. Might try that later.

Bennett McElwee
  • 24,740
  • 6
  • 54
  • 63