以下是三个可以让你装出对GraphQL熟悉的对话选项:1. GraphQL是如此强大和灵活,我们可以根据客户的需求精确获取数据,而不会浪费任何资源。2. 我们可以通过GraphQL的查询语言轻松地获取和过滤特定字段的数据,这种灵活性非常有用。3. GraphQL的可视化工具可以帮助我们更好地理解和调试数据查询,这样我们可以更快地解决问题
首先
在为GraphQL相关的开源软件做贡献的过程中,我总结了三个关于GraphQL的重要观点,这些在以前的GraphQL API开发中我没有意识到。希望这些总结对你在装懂的时候有所帮助,敬请使用!
1. GraphQL 的大部分都是字段吧。
我认为你知道GraphQL有Query、Mutation和Subscription这三个,大致上分配的角色如下:
-
- Query: データ取得用
-
- Mutation: データ変更用
- Subscription: サーバからのプッシュ用
可以创建一个名为”users”的查询来获取用户列表,或者创建一个名为”createUser”的突变来注册新用户。
在这里,称之为”users”或”createUser”为查询(Query)或变更(Mutation)也没有错,但准确来说,它们是”users”作为根对象字段的查询(Query)”或”createUser”作为根对象字段的变更(Mutation)”。
换句话说,”让我们创建一个用于获取用户列表的查询,称为users”可以被改写为”让我们将用于获取用户列表的users字段添加到查询对象中”,这样在GraphQL中更准确地表达,并且能够展示出你对此的理解。
当然,有可能只是觉得麻烦。
2. 真可惜,输入中没有 Union 类型呢
GraphQL的输入类型中没有Union类型。补充一下,Union类型表示A | B这样的一个类型,可以接收A或B中的任一类型。
另外,中文中有一个称为Union类型的输出选项。您可以直观地定义Union类型,如下所示。然而,如果您试图将其用作输入,系统会报错。
union Media = Book | Movie
这个规范因为习惯于丰富的类型定义的开发者反响不佳,所以提出了一个RFC,建议在输入中支持联合类型。接下来计划引入一个名为@oneOf的指令,这经历了一番周折。
在以往的GraphQL中,当想要在类型上保持强健时,例如要通过ID获取用户或者通过电子邮件获取用户,就需要分别定义userByID和userByEmail,这种情况经常出现。
type Query {
userByID(id: ID!): User
userByEmail(email: String!): User
}
通过使用@oneOf,您可以将下面的内容整合到一个名为”user”的查询中(准确地说是查询对象的字段)。由于@oneOf确保只指定id或email中的一个,因此该规范似乎对类型严格要求的人也是令人满意的。
type Query {
user(by: UserByInput!): User
}
input UserByInput @oneOf {
id: ID
email: String
}
参考:GraphQL即将推出新功能:oneof输入对象。
只有熟练使用ResolveInfo,GraphQL才能发挥其价值对吧。
请将ResolveInfo(正式名称为GraphQLResolveInfo)理解为在执行一些复杂操作时所必需的对象。
让我们以以下查询为例来考虑ResolveInfo的用法。这个查询是用来获取每个用户的id和姓名,并且获取与每个用户相关联的帖子(posts)的id和标题的查询。
query {
users {
id
name
posts {
id
title
}
}
}
在GraphQL中,对于查询中指定的每个字段,通过依次调用设置在各字段上的解析器来生成最终的返回值。对于上述查询,实际处理的流程如下所示。
-
- 调用根对象Query的users字段的解析器
-
- 如果(1)解析器的执行结果返回了N条数据(N > 0),则针对每个数据,将会调用id、name、posts字段的解析器N次
如果posts字段的解析器的执行结果返回了M条数据(M > 0),则针对每个数据,将会调用id、title字段的解析器M次
如果某个字段的解析器未设置,则它的默认行为是从父字段的解析器返回的值(对象)中返回自身字段名的属性。例如,如果(1)返回的值是[{ id: 1, name: “Jon”, posts: [] }],那么(2)中id字段的默认解析器将返回1,name字段将返回”Jon”,posts字段将返回[]。
换句话说,如果大本的“users”字段的解析器能够生成并返回指定字段的所有值,那么其他字段可以交给默认的解析器处理。在这个例子中,如果在“users”字段的解析器中,根据上述GraphQL查询生成类似以下的SQL,并从数据库中检索值,那将是很好的解决方法。
SELECT
User.id,
User.name,
Post.id as postId,
Post.title
FROM
User INNER JOIN Post ON User.id = Post.user_id
这样的GraphQL查询到SQL的转换机制在Hasura或者PostGraphile中被实现了(可能)。为了实现这一点,需要用到ResolveInfo。从ResolveInfo中获取查询中指定的字段,然后生成对应的SQL,这就是流程。
除此之外,还有其他原因可以使用ResolveInfo在根字段上进行集中处理,而不是将处理委托给各个字段。例如,这样做可以提高性能。在处理args的验证、权限控制等操作时,ResolveInfo可以发挥作用。
请参阅GraphQL.js的类型定义,了解可以从ResolveInfo中获得的具体值。
整理
-
- GraphQLって9割がたフィールドだよね
-
- インプットにUnion型がないのは残念だよね
- ResolveInfoを使いこなして初めてGraphQLに価値が生まれるよね
希望通过巧妙地使用这三个短语,能够使大家的单价等上升。如果对此感兴趣的话,请也欢迎查看本文所提到的关于OSS和GraphQL的教程。