Graphql-dotnet: Resolving a Dynamic List

Created on 13 Mar 2017  路  3Comments  路  Source: graphql-dotnet/graphql-dotnet

I am currently using MassiveORM to fetch my data. However, GraphQL is unable to access the properties on the dynamic object. Here is my resolver:

Resolver = new FuncFieldResolver<Task<List<dynamic>>>(context =>
                    {
                        var dataAcess = (IDataAccess) context.UserContext;
                        var whereClause = context.Arguments.ConvertToSql();
                        return dataAcess.AllAsync(reportTableName, whereClause);
                    })

GraphQL is throwing the following error:

{GraphQL.ExecutionError: Error trying to resolve ID. ---> System.InvalidOperationException: Expected to find property ID on ExpandoObject but it does not exist.
at GraphQL.Resolvers.NameFieldResolver.Resolve(ResolveFieldContext context)
at GraphQL.DocumentExecuter.d__12.MoveNext()
--- End of inner exception stack trace ---}

Because this is a List<dynamic>, it looks like GraphQL needs to cast each item to dynamic in order to fetch the property. Ex: ((dynamic)dynamicList[0]).ID. How can I accomplish this? Is there, perhaps, a func I can set for custom resolving?

Most helpful comment

My solution (not yet generified for all types, but...):

var schema = Schema.For(File.ReadAllText("GraphQL/schemas/schema.graphqls"));

var simulationType = schema.FindType("Simulation") as ObjectGraphType;
simulationType.Fields.ForEach(f => f.Resolver = new FuncFieldResolver<object>(ctx =>
{
    var o = ctx.Source as IDictionary<string, object>;
    if (o == null)
    {
        return null;
    }

    if (!o.ContainsKey(ctx.FieldName))
    {
        return null;                    
    }

    return o[ctx.FieldName];
}));

RegisterTypes(schema.AllTypes.ToArray());
Query.AddField(
    new FieldType()
    {
        Name = "simulations",
        ResolvedType = new ListGraphType(simulationType),
        Resolver = new FuncFieldResolver<List<dynamic>>(ctx =>
        {
            var simulations = _db.GetCollection<dynamic>(simulationType.Name);
            var result = simulations.Find(Builders<dynamic>.Filter.Empty).Limit(10).ToList();
            return result;
        })
    });
}

All 3 comments

I figured this out. FieldType has a Resolver property which helps address this.

@harsimranb Can you please post your solution? I am running into this exact issue - I can get arbitrary data from my database and I expect it to conform to the graph ql schema (it does). If I create the object in my resolver as an anonymous type, it works fine, but if I try to return dynamic objects it fails with:

GraphQL.ExecutionError: Error trying to resolve id. ---> System.InvalidOperationException: Expected to find property id on ExpandoObject but it does not exist.\n   at GraphQL.Resolvers.NameFieldResolver.Resolve(Object source, String name)\n  

My solution (not yet generified for all types, but...):

var schema = Schema.For(File.ReadAllText("GraphQL/schemas/schema.graphqls"));

var simulationType = schema.FindType("Simulation") as ObjectGraphType;
simulationType.Fields.ForEach(f => f.Resolver = new FuncFieldResolver<object>(ctx =>
{
    var o = ctx.Source as IDictionary<string, object>;
    if (o == null)
    {
        return null;
    }

    if (!o.ContainsKey(ctx.FieldName))
    {
        return null;                    
    }

    return o[ctx.FieldName];
}));

RegisterTypes(schema.AllTypes.ToArray());
Query.AddField(
    new FieldType()
    {
        Name = "simulations",
        ResolvedType = new ListGraphType(simulationType),
        Resolver = new FuncFieldResolver<List<dynamic>>(ctx =>
        {
            var simulations = _db.GetCollection<dynamic>(simulationType.Name);
            var result = simulations.Find(Builders<dynamic>.Filter.Empty).Limit(10).ToList();
            return result;
        })
    });
}
Was this page helpful?
0 / 5 - 0 ratings

Related issues

ildoc picture ildoc  路  4Comments

dimortizp picture dimortizp  路  3Comments

joemcbride picture joemcbride  路  4Comments

VladimirAkopyan picture VladimirAkopyan  路  4Comments

phoenixjun picture phoenixjun  路  4Comments