设为首页收藏本站
网站公告 | 这是第一条公告
     

 找回密码
 立即注册
缓存时间01 现在时间01 缓存数据 当你走完一段之后回头看,你会发现,那些真正能被记得的事真的是没有多少,真正无法忘记的人屈指可数,真正有趣的日子不过是那么一些,而真正需要害怕的也是寥寥无几。

当你走完一段之后回头看,你会发现,那些真正能被记得的事真的是没有多少,真正无法忘记的人屈指可数,真正有趣的日子不过是那么一些,而真正需要害怕的也是寥寥无几。

查看: 846|回复: 1

GraphQL在.NET 8中的全面实践指南(最新推荐)

[复制链接]

  离线 

TA的专栏

  • 打卡等级:热心大叔
  • 打卡总天数:232
  • 打卡月天数:0
  • 打卡总奖励:4028
  • 最近打卡:2025-08-02 15:22:28
等级头衔

等級:晓枫资讯-上等兵

在线时间
4 小时

积分成就
威望
0
贡献
448
主题
396
精华
0
金钱
5330
积分
910
注册时间
2023-1-7
最后登录
2025-8-25

发表于 2025-8-22 20:42:37 | 显示全部楼层 |阅读模式

一、GraphQL与.NET 8概述

GraphQL是一种由Facebook开发的API查询语言,它提供了一种更高效、更灵活的替代REST的方案。与REST不同,GraphQL允许客户端精确指定需要的数据结构和字段,避免了"过度获取"或"不足获取"的问题。

.NET 8对GraphQL的支持

.NET 8带来了多项性能改进和新特性,使其成为构建GraphQL服务的理想平台:

  • 性能提升:AOT编译、改进的JIT编译器
  • 最小API增强:简化GraphQL端点设置
  • 原生AOT支持:适合云原生GraphQL服务部署
  • 改进的依赖注入:更简洁的服务注册方式

二、环境准备与项目搭建

1. 创建.NET 8项目

  1. dotnet new web -n GraphQLDemo
  2. cd GraphQLDemo
复制代码

2. 添加必要的NuGet包

  1. dotnet add package HotChocolate.AspNetCore
  2. dotnet add package HotChocolate.Data
  3. dotnet add package Microsoft.EntityFrameworkCore.SqlServer
复制代码

三、基础GraphQL服务搭建

1. 定义数据模型

  1. // Models/Book.cs
  2. public class Book
  3. {
  4. public int Id { get; set; }
  5. public string Title { get; set; }
  6. public Author Author { get; set; }
  7. public DateTime PublishedDate { get; set; }
  8. }
  9. // Models/Author.cs
  10. public class Author
  11. {
  12. public int Id { get; set; }
  13. public string Name { get; set; }
  14. public ICollection<Book> Books { get; set; } = new List<Book>();
  15. }
复制代码

2. 配置DbContext

  1. // Data/AppDbContext.cs
  2. public class AppDbContext : DbContext
  3. {
  4. public AppDbContext(DbContextOptions<AppDbContext> options)
  5. : base(options) { }
  6. public DbSet<Book> Books { get; set; }
  7. public DbSet<Author> Authors { get; set; }
  8. protected override void OnModelCreating(ModelBuilder modelBuilder)
  9. {
  10. modelBuilder.Entity<Author>()
  11. .HasMany(a => a.Books)
  12. .WithOne(b => b.Author)
  13. .HasForeignKey(b => b.AuthorId);
  14. }
  15. }
复制代码

3. 注册GraphQL服务

  1. // Program.cs
  2. var builder = WebApplication.CreateBuilder(args);
  3. // 添加DbContext
  4. builder.Services.AddDbContext<AppDbContext>(options =>
  5. options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));
  6. // 添加GraphQL服务
  7. builder.Services
  8. .AddGraphQLServer()
  9. .AddQueryType<Query>()
  10. .AddMutationType<Mutation>()
  11. .AddProjections()
  12. .AddFiltering()
  13. .AddSorting();
  14. var app = builder.Build();
  15. app.MapGraphQL(); // 默认路径为/graphql
  16. app.Run();
复制代码

四、查询(Query)实现

1. 基本查询类型

  1. // GraphQL/Query.cs
  2. public class Query
  3. {
  4. [UseDbContext(typeof(AppDbContext))]
  5. [UseProjection]
  6. [UseFiltering]
  7. [UseSorting]
  8. public IQueryable<Book> GetBooks([ScopedService] AppDbContext context)
  9. => context.Books;
  10. [UseDbContext(typeof(AppDbContext))]
  11. public async Task<Book?> GetBookById(
  12. [ScopedService] AppDbContext context,
  13. int id)
  14. => await context.Books.FindAsync(id);
  15. }
复制代码

2. 复杂查询示例

  1. query {
  2. books(where: { title: { contains: "NET" } }, order: { publishedDate: DESC }) {
  3. title
  4. publishedDate
  5. author {
  6. name
  7. }
  8. }
  9. }
复制代码

五、变更(Mutation)实现

1. 基本变更操作

  1. // GraphQL/Mutation.cs
  2. public class Mutation
  3. {
  4. [UseDbContext(typeof(AppDbContext))]
  5. public async Task<AddBookPayload> AddBook(
  6. AddBookInput input,
  7. [ScopedService] AppDbContext context)
  8. {
  9. var book = new Book
  10. {
  11. Title = input.Title,
  12. PublishedDate = input.PublishedDate,
  13. AuthorId = input.AuthorId
  14. };
  15. context.Books.Add(book);
  16. await context.SaveChangesAsync();
  17. return new AddBookPayload(book);
  18. }
  19. }
  20. public record AddBookInput(string Title, DateTime PublishedDate, int AuthorId);
  21. public record AddBookPayload(Book Book);
复制代码

2. 输入类型与Payload模式

  1. mutation {
  2. addBook(input: {
  3. title: "Mastering GraphQL in .NET 8",
  4. publishedDate: "2023-11-01",
  5. authorId: 1
  6. }) {
  7. book {
  8. id
  9. title
  10. }
  11. }
  12. }
复制代码

六、高级特性实现

1. 数据加载器(DataLoader)优化

  1. // GraphQL/Query.cs
  2. public async Task<IEnumerable<Author>> GetAuthorsWithBooks(
  3. [Service] AppDbContext context,
  4. [Service] IResolverContext resolverContext)
  5. {
  6. var loader = resolverContext.BatchDataLoader<int, Author>(
  7. "authorsById",
  8. async (ids, ct) =>
  9. {
  10. var authors = await context.Authors
  11. .Where(a => ids.Contains(a.Id))
  12. .ToDictionaryAsync(a => a.Id, ct);
  13. return ids.Select(id => authors.TryGetValue(id, out var author) ? author : null);
  14. });
  15. // 假设我们有一些作者ID
  16. var authorIds = new[] { 1, 2, 3 };
  17. return await loader.LoadAsync(authorIds);
  18. }
复制代码

2. 订阅(Subscription)实现

  1. // GraphQL/Subscription.cs
  2. [ExtendObjectType("Subscription")]
  3. public class BookSubscriptions
  4. {
  5. [Subscribe]
  6. [Topic("BookAdded")]
  7. public Book OnBookAdded([EventMessage] Book book) => book;
  8. }
  9. // 在Mutation中发布事件
  10. [UseDbContext(typeof(AppDbContext))]
  11. public async Task<AddBookPayload> AddBook(
  12. AddBookInput input,
  13. [ScopedService] AppDbContext context,
  14. [Service] ITopicEventSender eventSender)
  15. {
  16. var book = new Book { /* ... */ };
  17. context.Books.Add(book);
  18. await context.SaveChangesAsync();
  19. await eventSender.SendAsync("BookAdded", book);
  20. return new AddBookPayload(book);
  21. }
复制代码

七、性能优化与安全

1. 查询复杂度分析

  1. builder.Services
  2. .AddGraphQLServer()
  3. .AddQueryType<Query>()
  4. .AddMutationType<Mutation>()
  5. .AddMaxExecutionDepthRule(5) // 限制查询深度
  6. .AddQueryCostOptions(options =>
  7. {
  8. options.DefaultCost = 1;
  9. options.MaxAllowedCost = 1000;
  10. });
复制代码

2. 认证与授权

  1. // 添加认证服务
  2. builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
  3. .AddJwtBearer(options => { /* 配置JWT */ });
  4. // 保护GraphQL端点
  5. builder.Services
  6. .AddGraphQLServer()
  7. .AddAuthorization()
  8. .AddHttpRequestInterceptor<AuthInterceptor>();
  9. // 实现拦截器
  10. public class AuthInterceptor : DefaultHttpRequestInterceptor
  11. {
  12. public override ValueTask OnCreateAsync(
  13. HttpContext context,
  14. IRequestExecutor requestExecutor,
  15. IQueryRequestBuilder requestBuilder,
  16. CancellationToken cancellationToken)
  17. {
  18. if (!context.User.Identity.IsAuthenticated)
  19. {
  20. throw new GraphQLException("未认证用户");
  21. }
  22. return base.OnCreateAsync(context, requestExecutor, requestBuilder, cancellationToken);
  23. }
  24. }
复制代码

八、.NET 8特有优化

1. AOT编译支持

  1. <PropertyGroup>
  2. <PublishAot>true</PublishAot>
  3. </PropertyGroup>
复制代码

2. 最小API集成

  1. app.MapGraphQL()
  2. .WithTags("GraphQL")
  3. .WithDescription("GraphQL API端点")
  4. .RequireAuthorization();
复制代码

3. 性能监控

  1. builder.Services
  2. .AddGraphQLServer()
  3. .AddInstrumentation(options =>
  4. {
  5. options.RequestDetails = RequestDetails.All;
  6. options.IncludeDocument = true;
  7. })
  8. .AddDiagnosticEventListener<PerformanceLogger>();
  9. public class PerformanceLogger : DiagnosticEventListener
  10. {
  11. public override void RequestProcessing(HttpContext context, IRequestExecutor executor, IQueryRequest request)
  12. {
  13. var stopwatch = Stopwatch.StartNew();
  14. base.RequestProcessing(context, executor, request);
  15. stopwatch.Stop();
  16. Console.WriteLine($"请求处理时间: {stopwatch.ElapsedMilliseconds}ms");
  17. }
  18. }
复制代码

九、测试GraphQL API

1. 使用Banana Cake Pop

HotChocolate内置了Banana Cake Pop这个GraphQL IDE,访问

  1. /graphql
复制代码
即可使用。

2. 单元测试示例

  1. [TestClass]
  2. public class GraphQLTests
  3. {
  4. [TestMethod]
  5. public async Task GetBooks_ReturnsValidData()
  6. {
  7. // 安排
  8. var executor = await new ServiceCollection()
  9. .AddGraphQLServer()
  10. .AddQueryType<Query>()
  11. .AddDbContext<AppDbContext>(options =>
  12. options.UseInMemoryDatabase("TestDB"))
  13. .BuildRequestExecutorAsync();
  14. // 执行
  15. var result = await executor.ExecuteAsync(@"
  16. query {
  17. books {
  18. title
  19. author {
  20. name
  21. }
  22. }
  23. }");
  24. // 断言
  25. Assert.IsFalse(result.Errors?.Any() ?? false);
  26. var books = result.ToJson();
  27. Assert.IsNotNull(books);
  28. }
  29. }
复制代码

十、部署与扩展

1. 容器化部署

  1. FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
  2. WORKDIR /src
  3. COPY . .
  4. RUN dotnet publish -c Release -o /app /p:PublishAot=true
  5. FROM mcr.microsoft.com/dotnet/aspnet:8.0
  6. WORKDIR /app
  7. COPY --from=build /app .
  8. ENTRYPOINT ["./GraphQLDemo"]
复制代码

2. 扩展架构建议

  • 联邦架构:使用HotChocolate Federation扩展
  • 缓存策略:实现查询缓存中间件
  • 限流:添加请求限流保护

结语

.NET 8为构建高性能GraphQL服务提供了坚实的基础,结合HotChocolate这样的成熟库,开发者可以快速构建灵活、高效的API服务。本文涵盖了从基础到高级的各个方面,希望能帮助您在.NET生态中充分利用GraphQL的优势。

实际项目中,建议根据具体需求选择合适的GraphQL特性,平衡灵活性与性能,并始终关注API的安全性和可维护性

到此这篇关于GraphQL在.NET 8中的全面实践指南(最新推荐)的文章就介绍到这了,更多相关GraphQL .NET实践内容请搜索晓枫资讯以前的文章或继续浏览下面的相关文章希望大家以后多多支持晓枫资讯!


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
晓枫资讯-科技资讯社区-免责声明
免责声明:以上内容为本网站转自其它媒体,相关信息仅为传递更多信息之目的,不代表本网观点,亦不代表本网站赞同其观点或证实其内容的真实性。
      1、注册用户在本社区发表、转载的任何作品仅代表其个人观点,不代表本社区认同其观点。
      2、管理员及版主有权在不事先通知或不经作者准许的情况下删除其在本社区所发表的文章。
      3、本社区的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,举报反馈:点击这里给我发消息进行删除处理。
      4、本社区一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
      5、以上声明内容的最终解释权归《晓枫资讯-科技资讯社区》所有。
http://bbs.yzwlo.com 晓枫资讯--游戏IT新闻资讯~~~

  离线 

TA的专栏

等级头衔

等級:晓枫资讯-列兵

在线时间
0 小时

积分成就
威望
0
贡献
0
主题
0
精华
0
金钱
16
积分
12
注册时间
2022-12-29
最后登录
2022-12-29

发表于 2025-8-31 13:21:02 | 显示全部楼层
路过,支持一下
http://bbs.yzwlo.com 晓枫资讯--游戏IT新闻资讯~~~
严禁发布广告,淫秽、色情、赌博、暴力、凶杀、恐怖、间谍及其他违反国家法律法规的内容。!晓枫资讯-社区
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

1楼
2楼

手机版|晓枫资讯--科技资讯社区 本站已运行

CopyRight © 2022-2025 晓枫资讯--科技资讯社区 ( BBS.yzwlo.com ) . All Rights Reserved .

晓枫资讯--科技资讯社区

本站内容由用户自主分享和转载自互联网,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。

如有侵权、违反国家法律政策行为,请联系我们,我们会第一时间及时清除和处理! 举报反馈邮箱:点击这里给我发消息

Powered by Discuz! X3.5

快速回复 返回顶部 返回列表