先简单对比以下GraphQL和WebAPI:GraphQL和Web API(如RESTful API)是用于构建和提供Web服务的不同技术。
在前面我们基础框架是基于WebAPI(REST FUL API)的模式去开发接口的,所有的响应数据都需要定义一个DTO结构,但是有些场景可能只需要某些字段,而后端又懒得定义新数据接口对接,这就会导致客户端获取到不必要的数据。在这种情况下,使用GraphQL就可以有较好的体验。
那么,在我们现有写好的Service中,如何快速集成GraphQL又无需复杂编码工作呢。这就是我们接下来要实现的了。
HotChocolate.AspNetCore是.NET一个老牌的GraphQL实现库,它可以让我们很快速的实现一个GraphQL Server。安装HotChocolate.AspNetCore的nuget,在Program中添加代码
builder.Services.AddGraphQLServer() app.MapGraphQL();
builder.Services.AddGraphQLServer()
app.MapGraphQL();
这样就完成一个GraphQLServer的集成。启动程序,访问https://localhost:7080/graphql/ 可以看到集成的界面。可以使用这个界面操作测试我们的graphql查询。
接下来实现一个基础的QueryType,用于扩展查询。
using HotChocolate.Authorization;namespace Wheel.Graphql{ [Authorize] public class Query : IQuery { } [InterfaceType] public interface IQuery { }}
using HotChocolate.Authorization;
namespace Wheel.Graphql
{
[Authorize]
public class Query : IQuery
}
[InterfaceType]
public interface IQuery
在AddGraphQLServer()后面添加代码
builder.Services.AddGraphQLServer() .AddQueryType<Query>() ;
.AddQueryType<Query>()
;
使用ExtendObjectType扩展Query类,方便接口拆分。
public interface IQueryExtendObjectType{}[ExtendObjectType(typeof(IQuery))]public class SampleQuery : IQueryExtendObjectType{ public List<string> Sample() { return new List<string> { "sample1", "sample2" }; }}[ExtendObjectType(typeof(IQuery))]public class Sample2Query : IQueryExtendObjectType{ public string Sample2(string id) { return id; }}
public interface IQueryExtendObjectType
[ExtendObjectType(typeof(IQuery))]
public class SampleQuery : IQueryExtendObjectType
public List<string> Sample()
return new List<string> { "sample1", "sample2" };
public class Sample2Query : IQueryExtendObjectType
public string Sample2(string id)
return id;
这里创建一个IQueryExtendObjectType空接口,用于获取所有需要扩展的QueryAPI约定所有扩展的Query需要继承IQueryExtendObjectType接口,并加上ExtendObjectType特性标签。封装AddGraphQLServer方法:
using HotChocolate.Execution.Configuration;using System.Reflection;namespace Wheel.Graphql{ public static class GraphQLExtensions { public static IRequestExecutorBuilder AddWheelGraphQL(this IServiceCollection services) { var result = services.AddGraphQLServer() .AddQueryType<Query>() ; var abs = Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory, "*.dll") .Where(x => !x.Contains("Microsoft.") && !x.Contains("System.")) .Select(x => Assembly.Load(AssemblyName.GetAssemblyName(x))).ToArray(); var types = abs.SelectMany(ab => ab.GetTypes() .Where(t => typeof(IQueryExtendObjectType).IsAssignableFrom(t) && typeof(IQueryExtendObjectType) != t)); if (types.Any()) { result = result.AddTypes(types.ToArray()); } return result; } }}
using HotChocolate.Execution.Configuration;
using System.Reflection;
public static class GraphQLExtensions
public static IRequestExecutorBuilder AddWheelGraphQL(this IServiceCollection services)
var result = services.AddGraphQLServer()
var abs = Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory, "*.dll")
.Where(x => !x.Contains("Microsoft.") && !x.Contains("System."))
.Select(x => Assembly.Load(AssemblyName.GetAssemblyName(x))).ToArray();
var types = abs.SelectMany(ab => ab.GetTypes()
.Where(t => typeof(IQueryExtendObjectType).IsAssignableFrom(t) && typeof(IQueryExtendObjectType) != t));
if (types.Any())
result = result.AddTypes(types.ToArray());
return result;
遍历所有IQueryExtendObjectType并加入GraphQLServer。启动项目访问https://localhost:7080/graphql/可以看到SchemaDefinition自动生成了我们的两个查询。
安装HotChocolate.AspNetCore.Authorization的Nuget包。在services.AddGraphQLServer()后面添加代码.AddAuthorization()
using HotChocolate.Execution.Configuration;using System.Reflection;namespace Wheel.Graphql{ public static class GraphQLExtensions { public static IRequestExecutorBuilder AddWheelGraphQL(this IServiceCollection services) { var result = services.AddGraphQLServer() .AddAuthorization() .AddQueryType<Query>() ; var abs = Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory, "*.dll") .Where(x => !x.Contains("Microsoft.") && !x.Contains("System.")) .Select(x => Assembly.Load(AssemblyName.GetAssemblyName(x))).ToArray(); var types = abs.SelectMany(ab => ab.GetTypes() .Where(t => typeof(IQueryExtendObjectType).IsAssignableFrom(t) && typeof(IQueryExtendObjectType) != t)); if (types.Any()) { result = result.AddTypes(types.ToArray()); } return result; } }}
.AddAuthorization()
未登录前执行查询,可以看到响应Error。获取一个token之后配置一下:再次请求,可以看到正常查询。
改造一下SampleQuery
[ExtendObjectType(typeof(IQuery))]public class SampleQuery : IQueryExtendObjectType{ public async Task<List<GetAllPermissionDto>> Sample([Service] IPermissionManageAppService permissionManageAppService) { var result = await permissionManageAppService.GetPermission(); return result.Data; }}
public async Task<List<GetAllPermissionDto>> Sample([Service] IPermissionManageAppService permissionManageAppService)
var result = await permissionManageAppService.GetPermission();
return result.Data;
打开https://localhost:7080/graphql/ 执行查询,可以看到正常返回。当我们需要过滤不查询某些字段时,只需要修改Query查询格式。
分页查询,添加一下User的分页查询代码。
public class SampleQuery : IQueryExtendObjectType{ public async Task<List<GetAllPermissionDto>> Sample([Service] IPermissionManageAppService permissionManageAppService) { var result = await permissionManageAppService.GetPermission(); return result.Data; } public async Task<Page<UserDto>> SampleUser(UserPageRequest pageRequest, [Service] IUserManageAppService userManageAppService) { var result = await userManageAppService.GetUserPageList(pageRequest); return result; }}
public async Task<Page<UserDto>> SampleUser(UserPageRequest pageRequest, [Service] IUserManageAppService userManageAppService)
var result = await userManageAppService.GetUserPageList(pageRequest);
测试:可以看到,很简单就可以把现有的API转换成GraphQL。只不过一些排序分页逻辑我们没有采用GraphQL的方式,而是使用我们自己的WebApi分页查询的模式。
轮子仓库地址https://github.com/Wheel-Framework/Wheel 欢迎进群催更。
原文链接:https://www.cnblogs.com/fanshaoO/p/17767098.html
本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728