Advice on building graphQL queries in c#

天涯浪子 提交于 2021-01-28 23:33:12

问题


I am working on a data migration project - API to API.

The destination API is graphQL, we have a number of objects to push into the destination and the shapes vary so I am looking for some advice on how best to dynamically build mutations/queries specifically in c#.

Currently we are just using templates and using find/replace routines to inject values. While this approach does work as the shapes of the data vary this becomes evermore complex and inelegant.

I am looking for any advice/pointers from anyone who have may have had a similar scenario or knows of any libraries I should look at.


回答1:


I'm working on a similar problem. As I see it there is a need model the GraphQL mutations and queries. Using C# objects to represent your entities, you can implement a custom serialiser the walks the properties (via reflection) and outputs the required GraphQL output.

I'll post back here with some sample code...




回答2:


Update - 13/02/2018

I have since updated this monstrosity to cater for nested sub selections and GraphQl enums so if anyone is interested here it is in GitHub

Orignal answer

I've got the same requirement. Couldn't find anything out there so I've come up with this very inelegant solution. It works for my scenarios so I'll post it here for anyone else looking for a solution.

 public static class GraphQlObjectParser
{
    public static string Parse(string queryType, string queryName, string[] subSelection, object @object = null, string objectTypeName = null)
    {
        var query = queryType + "{" + queryName;

        if (@object != null)
        {
            query += "(";

            if (objectTypeName != null)
            {
                query += objectTypeName + ":" + "{";
            }

            var queryData = string.Empty;
            foreach (var propertyInfo in @object.GetType().GetProperties())
            {
                var value = propertyInfo.GetValue(@object);
                if (value != null)
                {
                    var type = Nullable.GetUnderlyingType(propertyInfo.PropertyType) ?? propertyInfo.PropertyType;
                    var valueQuotes = type == typeof(string) ? "\"" : string.Empty;

                    var queryPart = char.ToLowerInvariant(propertyInfo.Name[0]) + propertyInfo.Name.Substring(1) + ":" + valueQuotes + value + valueQuotes;
                    queryData += queryData.Length > 0 ? "," + queryPart : queryPart;
                }
            }
            query += (objectTypeName != null ? queryData + "}" : queryData) + ")";
        }

        if (subSelection.Length > 0)
        {
            query += subSelection.Aggregate("{", (current, s) => current + (current.Length > 1 ? "," + s : s)) + "}";
        }

        query += "}";

        return query;
    }
}

This works for both queries and mutations. Examples of usage are:

var query = GraphQlObjectParser.Parse("query", "users", new[] { "id", "name" });

will give you

query{users{id,name}}

or

var query = GraphQlObjectParser.Parse("query", "user", new[] { "id", "name" }, new User { Id = 1 });

will give you

query{user(id:1){id,name}}

or

var query = GraphQlObjectParser.Parse("mutation", "user", new[] { "id", "name" }, new User { Id = 1, Name = "John" }, "data");

will give you

mutation{user(data:{id:1,name:"John"}){id,name}}

It'll work with enums which is why I needed this solution in the first place. You can pass in a sub selection without the object or the object without an object type name. I've tried to cover as many bases as possible although I've not yet catered for sub selection of a sub selection. I'll update here if/when I code this one.

Hope it helps someone.



来源:https://stackoverflow.com/questions/40871190/advice-on-building-graphql-queries-in-c-sharp

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!