1. 概述
GraphQL 已被广泛用作Web服务通信模式。其基本理念是为客户端应用程序提供灵活的使用方式。
在这篇教程中,我们将探讨灵活性的另一个方面:如何让GraphQL字段以不同的名称暴露出来。
2. GraphQL架构
让我们以一个具有不同作者的博客为例。GraphQL架构看起来像这样:
query {
recentPosts(count: 1, offset: 0){
id
title
text
category
author {
id
name
thumbnail
}
}
}
type Post {
id: ID!
title: String!
text: String!
category: String
authorId: Author!
}
type Author {
id: ID!
name: String!
thumbnail: String
posts: [Post]!
}
我们可以获取最近的帖子。每个post
都会附带其author
。查询结果如下:
{
"data": {
"recentPosts": [
{
"id": "Post00",
"title": "Post 0:0",
"text": "Post 0 + by author 0",
"category": null,
"author": {
"id": "Author0",
"name": "Author 0",
"thumbnail": "http://example.com/authors/0"
}
}
]
}
}
3. 以不同的名称暴露GraphQL字段
客户端应用程序可能需要使用first_author
字段。目前它正在使用author
。为了满足这个需求,我们有两种解决方案:
- 更新GraphQL服务器的架构定义
- 利用GraphQL中的别名概念
让我们逐个来看。
3.1. 修改架构
让我们更新post
的架构定义:
type Post {
id: ID!
title: String!
text: String!
category: String
first_author: Author!
}
author
字段并非简单的,它是一个复杂的字段。我们也需要更新处理方法来适应这个变化。
在PostController
中的@SchemaMapping
标记为author(Post post)
的方法,需要更改为getFirst_author(Post post)
。或者,可以在@SchemaMapping
的field
属性中添加新的字段名称。
以下是查询示例:
query{
recentPosts(count: 1,offset: 0){
id
title
text
category
first_author{
id
name
thumbnail
}
}
}
上述查询的结果如下:
{
"data": {
"recentPosts": [
{
"id": "Post00",
"title": "Post 0:0",
"text": "Post 0 + by author 0",
"category": null,
"first_author": {
"id": "Author0",
"name": "Author 0",
"thumbnail": "http://example.com/authors/0"
}
}
]
}
}
这种解决方案存在两个主要问题:
- 它改变了架构和服务器端实现
- 它强迫其他客户端应用遵循更新后的架构定义
这些问题与GraphQL提供的灵活性特性相矛盾。
3.2. GraphQL别名
在GraphQL中,别名允许我们在不改变架构定义的情况下将字段的结果重命名为任何我们想要的名字。要在查询中引入别名,只需在别名和冒号符号(:)之前放置GraphQL字段。
这里是一个演示查询的例子:
query {
recentPosts(count: 1,offset: 0) {
id
title
text
category
first_author:author {
id
name
thumbnail
}
}
}
上述查询的结果如下:
{
"data": {
"recentPosts": [
{
"id": "Post00",
"title": "Post 0:0",
"text": "Post 0 + by author 0",
"category": null,
"first_author": {
"id": "Author0",
"name": "Author 0",
"thumbnail": "http://example.com/authors/0"
}
}
]
}
}
请注意,查询本身请求的是第一个帖子。其他客户端应用可能会请求first_post
而不是recentPosts
。这时,别名就能派上用场。
query {
first_post: recentPosts(count: 1,offset: 0) {
id
title
text
category
author {
id
name
thumbnail
}
}
}
上述查询的结果如下:
{
"data": {
"first_post": [
{
"id": "Post00",
"title": "Post 0:0",
"text": "Post 0 + by author 0",
"category": null,
"author": {
"id": "Author0",
"name": "Author 0",
"thumbnail": "http://example.com/authors/0"
}
}
]
}
}
这两个例子清楚地展示了使用GraphQL时的灵活性。每个客户端应用可以根据需要自行更新,而服务器端的架构定义和实现保持不变。
4. 总结
在这篇文章中,我们研究了两种以不同的名称暴露GraphQL字段的方法。我们介绍了别名的概念,并通过示例解释了它是正确的方法。
如往常一样,本文的示例代码可在GitHub上找到。