使用C#实现GraphQL API:分步实战教程
在现代Web开发中,GraphQL正成为REST API越来越流行的替代方案。与每个端点返回固定数据结构的REST不同,GraphQL允许客户端精确请求所需的数据。在本教程中,我们将使用Hot Chocolate库在C#(.NET)中创建一个功能完善的GraphQL API。您将学习如何配置服务器、定义数据类型、实现查询和变更,以及添加订阅以实现实时更新。
什么是GraphQL以及为何与C#结合使用?
GraphQL是由Facebook开发的API查询语言。其主要优势包括:
- 查询灵活性 — 客户端决定需要获取哪些字段
- 单一入口点 — 所有查询共用一个端点
- 强类型系统 — 所有数据类型均被严格定义
- 无过度获取或获取不足 — 精确获取请求的数据
在.NET生态系统中,实现GraphQL的最佳库是Hot Chocolate。它支持GraphQL规范的所有功能,包括查询、变更和订阅。
项目配置与依赖安装
首先创建一个新的ASP.NET Core项目。打开终端或命令行并运行:
dotnet new webapi -n GraphQLDemocd GraphQLDemo现在安装Hot Chocolate包:
dotnet add package HotChocolate.AspNetCoredotnet add package HotChocolate.AspNetCore.Playground为我们的API创建数据模型。假设我们将处理图书和作者。创建一个Models文件夹并向其中添加以下类:
// Models/Author.cspublic class Author{ public int Id { get; set; } public string Name { get; set; } public ICollection<Book> Books { get; set; }}
// Models/Book.cspublic class Book{ public int Id { get; set; } public string Title { get; set; } public int AuthorId { get; set; } public Author Author { get; set; }}创建GraphQL模式和解析器
在GraphQL中,核心组件是类型、查询和变更。创建一个GraphQL文件夹并向其中添加以下文件:
// GraphQL/Query.cspublic class Query{ public IQueryable<Book> GetBooks([Service] ApplicationDbContext context) { return context.Books.Include(b => b.Author); }
public Book GetBook(int id, [Service] ApplicationDbContext context) { return context.Books.Include(b => b.Author).FirstOrDefault(b => b.Id == id); }
public IQueryable<Author> GetAuthors([Service] ApplicationDbContext context) { return context.Authors.Include(a => a.Books); }}
// GraphQL/Mutation.cspublic class Mutation{ public async Task<Book> AddBook(string title, int authorId, [Service] ApplicationDbContext context) { var book = new Book { Title = title, AuthorId = authorId }; context.Books.Add(book); await context.SaveChangesAsync(); return book; }
public async Task<Author> AddAuthor(string name, [Service] ApplicationDbContext context) { var author = new Author { Name = name }; context.Authors.Add(author); await context.SaveChangesAsync(); return author; }}现在在Program.cs中注册这些类:
// Program.csvar builder = WebApplication.CreateBuilder(args);
builder.Services .AddDbContext<ApplicationDbContext>(options => options.U