前言
你是否已经厌倦了 REST 风格的 API? 让我们来聊一下 GraphQL.
下面是 GraphQL 的定义:
GraphQL 既是一种用于 API 的查询语言也是一个满足你数据查询的运行时. GraphQL 对你的 API 中的数据提供了一套易于理解的完整描述, 使得客户端能够准确地获得它需要的数据, 而且没有任何冗余, 也让 API 更容易地随着时间推移而演进, 还能用于构建强大的开发者工具.
GraphQL 由 Facebook 开发, 始于 2012 年, 2015 年公开.
GraphQL 牛逼之处是它可以让客户端精确的查询它们想要的, 不附加额外的东西, 这样的话就很容易让客户端随着 API 的演进去使用.
GraphQL 提供了一种声明式的方式从服务器拉取数据. 你可以从 GraphQL 官网中了解到 GraphQL 的所有优点. 在这一系列博客中, 我将展示如何在 ASP.NET Core 中集成 GraphQL, 并使用 GraphQL 作为你的 API 查询语言.
使用 GraphQL 的声明式查询, 你可以自定义 API 返回的属性列表. 这与 REST API 中每个 API 只返回固定字段不同.
安装 GraphQL
为了在 C# 中使用 GraphQL, GraphQL 社区中提供了一个开源组件 graphql-dotnet . 本系列博客中我们都将使用这个组件.
首先我们创建一个空的 ASP.NET Core App
dotnet new web --name chatper1
然后我们添加对 graphql-dotnet 库的引用
dotnet add package GraphQL
创建第一个 Query
下面我们来创建一个 query 类, 我们将它命名为 HelloWorldQuery . graphql-dotnet 中, 查询类都需要继承 ObjectGraphType 类, 所以 HelloWorldQuery 的代码如下
- using GraphQL.Types;
- public class HelloWorldQuery : ObjectGraphType
- {
- public HelloWorldQuery()
- {
- Field<StringGraphType>(
- name: "hello",
- resolve: context => "world"
- );
- }
- }
这里你可能注意到我们使用了一个泛型方法 Field , 并传递了一个 GraphQL 的字符串类型 StringGraphType 来定义了一个 hello 字段, resolve 参数是一个 Func 委托, 在其中定义了如何返回当前字段的值, 这里我们是直接返回了一个字符串 hello.
查询类中的返回字段都是定义在查询类的构造函数中的
现在我们一个有了一个查询类, 下一步我们需要使用这个查询类构建一个结构 (schema).
在 Startup.cs 文件的 Configure 方法中, 使用以下代码替换原有代码
- var schema = new Schema {
- Query = new HelloWorldQuery()
- };
- App.Run(async (context) =>
- {
- var result = await new DocumentExecuter()
- .ExecuteAsync(doc =>
- {
- doc.Schema = schema;
- doc.Query = @"
- query {
- hello
- }
- ";
- }).ConfigureAwait(false);
- var JSON = new DocumentWriter(indent: true)
- .Write(result)
- await context.Response.WriteAsync(JSON);
- });
DocumentExecuter 类的 ExecuteAsync 方法中我们定义 Action 委托, 并通过这个委托设置了一个 ExecutionOptions 对象. 这个对象初始化了我们定义的结构 (schema), 并执行了我们定义的查询字符串.
doc.Query 定义了一个查询字符串
最终查询执行的结果会通过 DocumentWriter 类实例的 Write 被转换成一个 JSON 字符串
下面我们来运行一下这个程序
dotnet run
你将在浏览器中看到以下结果
- {
- "data": {
- "hello": "world"
- }
- }
从以上的例子中, 你会发现使用 GraphQL 并不像想象中那么难. 下面我们可以在 HelloWorldQuery 类的构造函数中再添加一个字段 howdy , 并指定这个字段会返回一个字符串 universe .
- Field<StringGraphType>(
- name: "howdy",
- resolve: context => "universe"
- );
然后我们继续修改 Startup 类中的 Configure 方法, 修改我们之前定义的 query
- var schema = new Schema {
- Query = new HelloWorldQuery()
- };
- App.Run(async (context) =>
- {
- var result = await new DocumentExecuter()
- .ExecuteAsync(doc =>
- {
- doc.Schema = schema;
- doc.Query = @"
- query {
- hello
- howdy
- }
- ";
- }).ConfigureAwait(false);
- var JSON = new DocumentWriter(indent: true)
- .Write(result)
- await context.Response.WriteAsync(JSON);
- });
重新启动项目后, 结果如下
- {
- "data": {
- "hello": "world",
- "howdy": "universe"
- }
- }
总结
本篇我们只是接触了 GraphQL 的一些皮毛, 你可能会对 GraphQL 声明式行为有很多问题, 没有关系, 后续博客中, 我们慢慢解开 GraphQL 的面纱. 下一篇我们将介绍如何创建一个中间件 (Middleware)
本篇源代码: https://github.com/lamondlu/GraphQL_Blogs (本地下载)
来源: https://www.jb51.net/article/150172.htm