GraphQL.NET dynamic field type

1.6k views Asked by At

I'm trying to add an object to my GraphQL.NET model, but I'm having a problem with one of the fields. The original class is

public class ShowCriterion
{
    public string RelatedEntity { get; set; }
    public object MatchValue { get; set; }
}

This takes a materialized path (like Person.Address.ZipCode), and compares it with the MatchValue. Problem is, MatchValue can be quite a lot of different things: boolean, int, string, List/array, DateTime, etc.

My first try was to create the GraphQL class as follows:

    public partial class ShowCriterionQL : ObjectGraphType<ShowCriterion>
    {
        public ShowCriterionQL()
        {
            Field(x => x.RelatedEntity, type: typeof(StringGraphType));
            Field(x => x.MatchValue, type: typeof(ObjectGraphType));
        }
    }

But it gives the following error:

GraphQL.Validation.ValidationError: Field matchValue of type ObjectGraphType must have a sub selection

If I make it a StringGraphType it will convert some values correctly (e.g. boolean true becomes "True"), but I really don't like this solution as it would require special handling on the client side. I also haven't explored all the possible types to see what happens with an array or a DateTime.

Is there any way to do this in GraphQL.NET?

(In searching I found several resources for dealing with type parameters, but that isn't really helpful to what I'm doing, since I use a generic object and use reflection at runtime to determine how to handle a particular value. I also found this unanswered question which is very similar...but sadly unanswered.)

1

There are 1 answers

0
tv31 On

You can use the AnyScalarGraphType but note that it is not recognized by the graphql clients although the query having it works fine when executed.

AnyScalarGraphType : https://github.com/graphql-dotnet/graphql-dotnet/blob/master/src/GraphQL/Utilities/Federation/AnyScalarGraphType.cs

GraphQL client issue : https://github.com/graphql/graphiql/issues/1705

You can also create a custom scalar type of your own.