问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

.NET使用Graphql的演示——新一代的API交互

创作时间:
作者:
@小白创作中心

.NET使用Graphql的演示——新一代的API交互

引用
1
来源
1.
https://www.cnblogs.com/weskynet/p/18471829

GraphQL是什么?先来一段AI给的回答:

GraphQL是一种为API设计的查询语言,与REST相比,它提供了更高效、强大和灵活的方法来与数据交互。GraphQL由Facebook于2012年开发,并于2015年开源。其主要的优势在于能够允许客户端精确地指定他们需要的数据,从而避免了过度获取或数据不足的问题。

主要特性

  • 精确获取需要的数据:客户端可以精确指定需要的数据字段,避免过度获取或数据不足的问题。
  • 单一端点:所有数据请求都通过一个统一的端点进行,简化了API的使用。
  • 类型系统:使用类型系统来定义数据结构,增强了数据的可读性和可维护性。
  • 查询与修改:支持查询(Query)、修改(Mutation)和订阅(Subscription)三种操作类型。
  • 实时数据(Subscription):支持实时数据推送,可以实现类似WebSocket的效果。

优势和局限

优势:

  • 减少数据传输:只返回客户端请求的数据,减少了不必要的数据传输。
  • 减少请求数:多个数据需求可以在单一查询中解决,减少了网络请求次数。
  • 灵活性高:客户端可以自由构造查询,无需服务器频繁更新API。

局限:

  • 复杂查询性能问题:如果不加限制地进行深度查询或大规模的数据嵌套,可能会对服务器性能造成影响。
  • 缓存策略:相比于REST的URL级别缓存,GraphQL需要更复杂的缓存策略来优化性能。
  • 学习曲线:对于开发者来说,需要学习新的查询语法及其底层实现。

接下来,我们通过一个实际的项目演示,展示如何在.NET中使用GraphQL进行API交互。

服务端实现

  1. 创建一个Web API项目作为服务端,添加必要的NuGet包:

  1. 新建Queries文件夹,用来存放查询使用的类和方法。例如,新增一个测试用的类和string类型返回值的方法 Hello()
public class TestQuery
{
    public string Hello() => "Hello, GraphQL!";
}
  1. 在启动项或Program.cs中,添加GraphQL服务,并注册Query类型:
builder.Services
    .AddGraphQLServer()
    .AddQueryType<TestQuery>();
  1. 映射GraphQL端点:
app.MapGraphQL();

运行程序后,可以通过GraphQL Playground进行查询测试。例如,在浏览器中访问http://localhost:5264/graphql/,输入查询语句:

query {
    hello
}

客户端实现

  1. 创建一个控制台项目作为客户端,添加必要的NuGet包:
<PackageReference Include="GraphQL.Client" Version="4.6.1" />
<PackageReference Include="GraphQL.Client.Serializer.Newtonsoft" Version="4.6.1" />
  1. 在客户端代码中,创建GraphQL客户端并发送查询请求:
var client = new GraphQLHttpClient("http://localhost:5264/graphql", new NewtonsoftJsonSerializer());
var request = new GraphQLRequest
{
    Query = @"query {
        hello
    }"
};
var response = await client.SendQueryAsync<HelloResponse>(request);
Console.WriteLine(response.Data.Hello);

拓展演示

接下来,我们演示如何处理嵌套实体类和复杂查询。例如,创建一个包含子集合的实体类:

public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
    public List<Address> Addresses { get; set; }
}

public class Address
{
    public string City { get; set; }
    public string Street { get; set; }
}

在查询时,可以灵活地选择需要的字段:

query {
    person {
        name
        addresses {
            city
        }
    }
}

修改操作(Mutation)

  1. 新建Mutations文件夹,用来存放增删改操作的类。例如,创建一个测试用的Mutation类:
public class TestMutation
{
    public bool OtherOperation(OtherOperationInput input)
    {
        // 模拟业务操作
        return true;
    }
}

public class OtherOperationInput
{
    public string Address { get; set; }
    public string City { get; set; }
    public string Phone { get; set; }
}
  1. 在Program.cs中注册Mutation类型:
builder.Services
    .AddGraphQLServer()
    .AddMutationType<TestMutation>();
  1. 在客户端发送Mutation请求:
var request = new GraphQLRequest
{
    Query = @"mutation{
        otherOperation(info:{address:""龙岗区宝龙街道"",city:""大大大深圳"",phone:""10100011""})
    }"
};
var response = await client.SendQueryAsync<object>(request);
Console.WriteLine(response.Data);

数据推送和订阅(Subscription)

  1. 新建Subscriptions文件夹,用来存放所有与消息推送和订阅相关的定义类。例如,创建一个测试用的Subscription类:
public class TestSub
{
    public IObservable<string> OnTestPublish([EventStreamConnection] IEventStreamConnection connection)
    {
        return connection.ToObservable<string>();
    }
}
  1. 在服务端注册Subscription类型:
builder.Services
    .AddGraphQLServer()
    .AddSubscriptionType<TestSub>()
    .AddInMemorySubscriptions(); // 默认消息持久化(生产情况建议更换)
  1. 在客户端实现订阅:
var option = new GraphQLHttpClientOptions
{
    EndPoint = new Uri("http://localhost:5264/graphql"),
    WebSocketEndPoint = new Uri("ws://localhost:5264/graphql")
};
using var client = new GraphQLHttpClient(option, new NewtonsoftJsonSerializer());

var subscriptionRequest = new GraphQLRequest
{
    Query = @"
    subscription {
        onTestPublish
    }"
};

var subscriptionStream = client.CreateSubscriptionStream<OnTestPublishResponse>(subscriptionRequest);
var subscription = subscriptionStream.Subscribe(
    response =>
    {
        if (response.Errors != null)
        {
            Console.WriteLine("Error occurred: " + response.Errors);
        }
        else
        {
            Console.WriteLine($"Received message: {response.Data.OnTestPublish}");
        }
    },
    error => Console.WriteLine($"Subscription error: {error.Message}"),
    () => Console.WriteLine("Subscription completed."));

需要注意的是,使用AddInMemorySubscriptions方法在生产环境中存在一些问题,例如可扩展性差、数据持久性缺失等。在生产环境中,建议使用基于Redis的持久化方案。

通过以上步骤,我们完成了在.NET中使用GraphQL进行API交互的完整演示,包括查询、修改和订阅等核心功能。GraphQL的灵活性和强大功能使其成为现代API开发的重要选择之一。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号