GraphQL

6 篇文章 0 订阅
这篇博客展示了如何将GraphQL集成到.NET Core应用程序中,创建了一个使用GraphiQL的示例,并提供了用于查询和突变的示例代码。通过GraphQL.Server.Transports.AspNetCore.SystemTextJson和GraphQL.Server.Ui.GraphiQL包,实现了GraphQL服务器的功能。此外,还涉及了数据源管理和查询解析的实现。
摘要由CSDN通过智能技术生成

GraphQL集成与.netcore服务

引用:

 

  <ItemGroup>
    <PackageReference Include="GraphQL.Server.Transports.AspNetCore.SystemTextJson" Version="5.2.2" />
    <PackageReference Include="GraphQL.Server.Ui.GraphiQL" Version="7.1.1" />
    <PackageReference Include="Grpc.AspNetCore" Version="2.27.0" />
  </ItemGroup>

代码: 

    /// <summary>
    /// Startup.cs
    /// </summary>
    public class Startup
    {
        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddGrpc().Services
                .AddControllers();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseGraphQLGraphiQL();
            app.UseRouting();

            app.Use(async (context, next) =>
            {
                if (context.Request.Path.StartsWithSegments("/graphql"))
                {
                    GraphQLRequest request;
                    using (var streamReader = new StreamReader(context.Request.Body))
                    {
                        request = JsonConvert.DeserializeObject<GraphQLRequest>(await streamReader.ReadToEndAsync());
                        var schema = new Schema() { Query = GroupQurey.Instance, Mutation = GroupQurey.Instance };
                        var result = await new DocumentExecuter()
                               .ExecuteAsync(doc =>
                               {
                                   doc.Schema = schema;
                                   doc.Query = request.Query;
                                   //!! Dictionary do not inherit from IDictionary
                                   doc.Inputs = JsonConvert.SerializeObject(request.Variables).ToInputs(); ;
                                   doc.OperationName = request.OperationName;
                                   doc.UnhandledExceptionDelegate += (ex) =>
                                   {
                                       int a = 10;
                                   };
                               }).ConfigureAwait(false);
                        var json = await new DocumentWriter(indent: true).WriteToStringAsync(result);
                        await context.Response.WriteAsync(json);
                    }
                }
                else
                    await next.Invoke();
            });

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapDefaultControllerRoute();
                endpoints.MapControllers();

                endpoints.MapGrpcService<GreeterService>();

                endpoints.MapGet("/_proto", async ctx =>
                {
                    ctx.Response.ContentType = "text/plain";
                    using var fs = new FileStream(Path.Combine(env.ContentRootPath, "Protos", "greet.proto"), FileMode.Open, FileAccess.Read);
                    using var sr = new StreamReader(fs);
                    while (!sr.EndOfStream)
                    {
                        var line = await sr.ReadLineAsync();
                        if (line != "/* >>" || line != "<< */")
                        {
                            await ctx.Response.WriteAsync(line);
                        }
                    }
                });

            });
        }
    }

    public class GraphQLRequest
    {
        [JsonProperty(propertyName: "query")]
        public string Query;

        [JsonProperty(propertyName: "variables")]
        public Dictionary<string, object> Variables;

        [JsonProperty(propertyName: "operationName")]
        public string OperationName;
    }
    /// <summary>
    /// GroupQuery.cs
    /// </summary>
    public class GroupQurey : ObjectGraphType
    {
        private static GroupQurey _instance;
        public static GroupQurey Instance
        {
            get
            {
                if (_instance == null)
                    _instance = new GroupQurey();
                return _instance;
            }
        }

        private GroupQurey()
        {
            Name = "group";
            Field<ItemType>("item",
                arguments: new QueryArguments(
                    new QueryArgument<IntGraphType> { Name = "index" },
                    new QueryArgument<StringGraphType> { Name = "name" }),
                resolve: context =>
                {
                    var index = context.GetArgument<int?>("index");
                    var name = context.GetArgument<string>("name");

                    return DataSource.Instance().GetItem(index, name);
                });
            Field<ListGraphType<ItemType>>("items",
                arguments: new QueryArguments(
                    new QueryArgument<IntGraphType> { Name = "page", DefaultValue = 0 },
                    new QueryArgument<IntGraphType> { Name = "size", DefaultValue = 5 }),
                resolve: context =>
                {
                    var page = context.GetArgument<int>("page");
                    var size = context.GetArgument<int>("size");
                    return DataSource.Instance().GetItems(page, size);
                });
            Field<ItemType>("addItem",
                arguments: new QueryArguments(
                    new QueryArgument<NonNullGraphType<ItemInputType>> { Name = "item" }),
                resolve: context =>
                {
                    var item = context.GetArgument<Item>("item");
                    return DataSource.Instance().Add(item);
                });
        }
    }

    public class Item
    {
        /// <summary>
        /// !! must property instead of field
        /// </summary>
        public int Index { get; set; }
        public string Name { get; set; }
        public string URL { get; set; }
    }

    public class ItemType : ObjectGraphType<Item>
    {
        public ItemType()
        {
            Name = "Item";
            Field("index", P => P.Index);
            Field("name", p => p.Name);
            Field("url", p => p.URL, nullable: true);
        }
    }
    public class ItemInputType : InputObjectGraphType<Item>
    {
        public ItemInputType()
        {
            Name = "ItemInput";
            Field("name", p => p.Name);
            Field("url", p => p.URL, nullable: true);
        }
    }
    public class DataSource
    {
        private object _lock = new object();
        private static DataSource _instance;
        public static DataSource Instance()
        {
            if (_instance == null)
                _instance = new DataSource();
            return _instance;
        }

        private DataSource()
        {
            for (int i = 0; i < 100; i++)
            {
                _items.Add(new Item { Index = i, Name = $"name{i}", URL = string.Empty });
            }
            _items.Add(new Item { Index = 100, Name = "name100" });
        }
        private List<Item> _items = new List<Item>();
        public List<Item> GetItems(int page, int size)
        {
            return _items.Skip(page * size).Take(size).ToList();
        }
        public Item GetItem(int? index, string name)
        {
            if (index != null)
                return _items.FirstOrDefault(p => p.Index == index);
            else if (name != null)
                return _items.FirstOrDefault(p => p.Name == name);
            else
                return _items[0];
        }
        public Item Add(Item item)
        {
            Item tmp = new Item { Index = -1, Name = item.Name, URL = item.URL };

            lock (_lock)
            {
                tmp.Index = _items.Count();
                _items.Add(tmp);
            }
            return tmp.Index == -1 ? null : tmp;
        }

    }
#GraphiQL 

mutation addItem($add: ItemInput!) {
  add_result: addItem(item: $add) {
    ...member
  }
}

query queryPage($page: Int, $size: Int) {
  items(page: $page, size: $size) {
    ...member
  }
}

query getItemByIndexOrName($index: Int, $name: String) {
  index_result: item(index: $index) {
    ...member
  }
  name_result: item(name: $name) {
    ...member
  }
}

fragment member on Item {
  index
  name
  url
}


#Variables
{
	"index": 3,
  "name": "name100",
  "page":0,
  "size":200,
  "add": {"name":"addItem","url":""}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值