I have an extending property needs to be filterable, however it fetches the data from a different data source. That means the default filtering won’t work, as the query cannot be translated properly.
I want to create a dummy filtertype handler, then apply the filter manually based on the query context.
public class User
{
public string? UserName { get; set; }
}
public class ProjectDetailListing
{
public bool? isPublic { get; set; }
}
[ExtendObjectType(typeof(User))]
public class UserExtensions
{
public async Task<ProjectDetailListing?> Listing(
[Parent] User parentObject,
ProjectListingDataLoader dataLoader,
CancellationToken cancellationToken
)
{
//fetch data from a different db
}
}
public class CustomFilteringConvention : FilterConvention
{
protected override void Configure(IFilterConventionDescriptor descriptor)
{
descriptor.AddDefaults();
descriptor
.BindRuntimeType<User, UserFilterInput>();
}
}
public class UserFilterInput : FilterInputType<User>
{
protected override void Configure(
IFilterInputTypeDescriptor<User> descriptor)
{
descriptor.Field("listing").Type<FilterInputType<ProjectDetailListing>>().Description("project listing");
}
}
Now I got the following errors.
HotChocolate.SchemaException: For more details look at the `Errors` property.
1. For the field listing of type UserFilterInput was no handler found.
at HotChocolate.Data.Filters.FilterTypeInterceptor.OnBeforeCompleteType(ITypeCompletionContext completionContext, DefinitionBase definition, IDictionary`2 contextData)
at HotChocolate.Configuration.AggregateTypeInterceptor.OnBeforeCompleteType(ITypeCompletionContext completionContext, DefinitionBase definition, IDictionary`2 contextData)
at HotChocolate.Types.TypeSystemObjectBase`1.CompleteType(ITypeCompletionContext context)
1 Answer
In the end, I created the custom filter to override the default behavior
public class UserFilterInput : FilterInputType<User>
{
protected override void Configure(
IFilterInputTypeDescriptor<User> descriptor)
protected override void Configure(
IFilterInputTypeDescriptor<SearchProjectsResponseResult> descriptor)
{
descriptor.Field("listing")
.Type<FilterInputType<ProjectDetailListing>>()
.Description("project listing");
.Extend()
.OnBeforeCreate(_ => _.Handler = new DummyHandler());
}
}
public class DummyHandler : QueryableDefaultFieldHandler
{
public override bool TryHandleEnter(
QueryableFilterContext context,
IFilterField field,
ObjectFieldNode node,
[NotNullWhen(true)] out ISyntaxVisitorAction? action)
{
Expression<Func<SearchProjectsResponseResult, bool>> expression =
_ => true;
var invoke = Expression.Invoke(expression, context.GetInstance());
context.GetLevel().Enqueue(invoke);
action = SyntaxVisitor.SkipAndLeave;
return true;
}
}