.NET 平台上 GraphQL 入门
GraphQL 是一种 API 查询语言,它允许客户端只获取真正需要的数据。与 REST 不同(REST 的响应结构由服务器硬性定义),GraphQL 可以灵活地构建查询。在本教程中,我们将使用 Hot Chocolate 框架(.NET 最流行的解决方案)在 C# 中创建一个完整的 GraphQL API。
我们将从安装开始,逐步深入到创建包含变更和订阅的复杂查询。本文面向熟悉 C# 和 ASP.NET Core 基础的开发者。
1. 项目设置与依赖安装
首先,创建一个新的 ASP.NET Core 项目。你可以使用 Visual Studio、Rider 或命令行。
dotnet new web -n GraphQLDemo
cd GraphQLDemo
现在安装 Hot Chocolate 包——在 .NET 中使用 GraphQL 的主要工具:
dotnet add package HotChocolate.AspNetCore
另外,为了通过 GraphQL IDE (Banana Cake Pop) 处理查询,安装:
dotnet add package HotChocolate.AspNetCore.Playground
1.1 Program.cs 基本配置
打开 Program.cs 文件并配置服务:
var builder = WebApplication.CreateBuilder(args);
builder.Services
.AddGraphQLServer()
.AddQueryType<Query>();
var app = builder.Build();
app.MapGraphQL();
app.Run();
注意:我们注册了 Query——这是用于读取数据的根类型。目前它是空的,但稍后我们会填充它。
2. 创建数据模型和第一个查询
GraphQL 使用类型工作。创建一个简单的 Book 模型:
public class Book
{
public int Id { get; set; }
public string Title { get; set; }
public string Author { get; set; }
public int Year { get; set; }
}
现在定义 Query 类,它将返回数据:
public class Query
{
private static List<Book> _books = new()
{
new Book { Id = 1, Title = "1984", Author = "George Orwell", Year = 1949 },
new Book { Id = 2, Title = "Clean Code", Author = "Robert C. Martin", Year = 2008 }
};
public IQueryable<Book> GetBooks() => _books.AsQueryable();
public Book? GetBookById(int id) => _books.FirstOrDefault(b => b.Id == id);
}
启动应用程序并打开 http://localhost:5000/graphql。你将看到 Banana Cake Pop——内置的用于测试查询的 IDE。尝试执行:
{
books {
title
author
}
}
你将只获得请求的字段——这就是 GraphQL 的强大之处。
3. 用于修改数据的变更
变更是 REST 中 POST/PUT/DELETE 的对应物。它们允许修改服务器上的数据。让我们添加添加新书籍的功能。
3.1 定义输入类型
为变更输入数据创建一个类:
public class AddBookInput
{
public string Title { get; set; }
public string Author { get; set; }
public int Year { get; set; }
}
3.2 实现变更
添加 Mutation 类:
public class Mutation
{
private static List<Book> _books = new()
{
new Book { Id = 1, Title = "1984", Author = "George Orwell", Year = 1949 },
new Book { Id = 2, Title = "Clean Code", Author = "Robert C. Martin", Year = 2008 }
};
public Book AddBook(AddBookInput input)
{
var newBook = new Book
{
Id = _books.Max(b => b.Id) + 1,
Title = input.Title,
Author = input.Author,
Year = input.Year
};
_books.Add(newBook);
return newBook;
}