有关在c#中构建graphQL查询的建议

时间:2016-11-29 16:43:39

标签: c# graphql

我正在开发数据迁移项目 - API API。

目标API是graphQL,我们有许多对象可以推送到目的地并且形状各不相同所以我正在寻找一些关于如何最好地动态构建c#中的突变/查询的建议。

目前我们只是使用模板并使用查找/替换例程来注入值。虽然这种方法确实起作用,因为数据的形状各不相同,但这变得越来越复杂和不优雅。

我正在寻找任何可能有类似情况或知道我应该看的任何库的人的建议/指示。

2 个答案:

答案 0 :(得分:4)

更新 - 13/02/2018

我已经更新了这个怪物,以满足嵌套的子选择和GraphQl枚举,所以如果有人对此感兴趣,它就在GitHub

原始回答

我有同样的要求。无法找到任何东西,所以我提出了这个非常不优雅的解决方案。它适用于我的场景,所以我会在这里发布它给其他寻找解决方案的人。

 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;
    }
}

这适用于查询和突变。用法示例如下:

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

会给你

query{users{id,name}}

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

会给你

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

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

会给你

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

它将使用枚举,这就是我首先需要这个解决方案的原因。您可以传入没有对象或对象的子选择而没有对象类型名称。虽然我还没有提供亚选择的子选择,但我试图尽可能多地覆盖基数。如果我在编写此代码时,我会在此处更新。

希望它有所帮助。

答案 1 :(得分:1)

我正在研究类似的问题。正如我所看到的那样,需要对GraphQL突变和查询进行建模。使用C#对象来表示您的实体,您可以实现一个自定义序列化器来遍历属性(通过反射)并输出所需的GraphQL输出。

我将在这里发布一些示例代码...