子解析器中的 Graphql-Access 参数
Graphql-Access arguments in child resolvers
我正在使用 apollo-server 和 apollo-graphql-tools,我有以下架构
type TotalVehicleResponse {
totalCars: Int
totalTrucks: Int
}
type RootQuery {
getTotalVehicals(color: String): TotalVehicleResponse
}
schema {
query: RootQuery
}
Resolver函数是这样的
{
RootQuery: {
getTotalVehicals: async (root, args, context) => {
// args = {color: 'something'}
return {};
},
TotalVehicleResponse: {
totalCars: async (root, args, conext) => {
// args is empty({}) here
.........
.........
},
totalTrucks: async (root, args, conext) => {
// args is empty({}) here
.........
.........
}
}
}
}
我的问题是如何在任何子解析器中访问根解析器 (getTotalVehicals
) 中可用的 args
?
args
严格引用查询中对该字段提供的参数。如果您希望子解析器可以使用值,您可以简单地从父解析器 return 它们。
{
RootQuery: {
getTotalVehicles: async (root, args, context) => {
return { color: args.color };
},
TotalVehicleResponse: {
totalCars: async (root, args, context) => {
// root contains color here
},
totalTrucks: async (root, args, context) => {
// root contains color here
}
}
}
}
如果您知道自己正在使用 variables,除了公认的答案之外,还有另一种方法,即使用解析器函数的第四个参数:info
.
此 info
参数在其他字段中包含一个字段 variableValues
。
该字段并不严格包含父级的 args
,但如果您的操作是使用传递给父级解析器的变量执行的,那么您将可以通过所有相关的 info.variableValues 访问它们解析器函数。
因此,如果您的操作是这样调用的,例如:
query GetTotalVehicalsOperation($color: String) {
getTotalVehicals(color: $color) {
totalCars
totalTrucks
}
}
... 变量:{color: 'something'}
您将可以访问来自其他解析器的变量:
{
RootQuery: {
getTotalVehicles: async (root, args, context, info) => {
//info.variableValues contains {color: 'something'}
return {};
},
TotalVehicleResponse: {
totalCars: async (root, args, context, info) => {
//same here: info.variableValues contains {color: 'something'}
},
totalTrucks: async (root, args, context, info) => {
//and also here: info.variableValues contains {color: 'something'}
}
}
}
}
了解更多关于 变量 在 GraphQL 中的使用
请参考这些 link(您可以在 5 分钟内完成这些 link)
https://graphql.org/learn/queries/#operation-name
https://graphql.org/learn/queries/#variables
https://graphql.org/learn/queries/#fragments
https://graphql.org/learn/queries/#using-variables-inside-fragments
您将更加掌握操作名称、变量、片段以及片段内变量的使用。
它将帮助您更多地了解解析器函数的 info 参数。
TLDR:将您的 参数 添加到 字段
(客户端)更改自:
Car(type: $type, materialType: $materialType){
id
material
name
...
}
(客户端)收件人:
Car(type: $type){
id,
material(materialType: $materialType) // moved here
name
...
}
然后,在您的服务器 fieldResolver
中访问您的参数(在本例中为 material
字段)。
更长的版本
尽量不要通过 root
传递您的参数,除了 IDs
、arguments that is not from client
或 a parent object
,其他任何使用 字段级参数 (除非你有非常好的理由不)
为什么?
有几个原因:
紧耦合
它会导致耦合并且很难扩展模式
- 来自评论区的@Bruno Ribeiro:
难以排除故障
一个级别还是可以的,但是当你公司的某个人找到了一种方法将论点深入到根源时,很难调试它是如何丢失的。
向children
泄露不必要的信息
通过 root 传递参数也意味着传递给每个其他 child,无论是否需要。
混淆了parentobject和参数
您的 parent object 可能与参数具有相同的 属性 键,例如:offset
,通过提供另一个偏移量,您可能会得到不希望的结果。
如何?
一个简单的查询可以由此增长:
[Root] Car(
color:white,
type:sedan,
seat:leather
) {
id,
seat,
numberOfPassengers,
...
}
为此:
[Root] Car(
color:white,
type:sedan,
seat:leather,
seatColor:black,
rimColor: blue,
rimShape: OutOfTheWorld,
...
) {
id,
seat,
numberOfPassengers,
...
}
您可以这样做,而不是四处传递参数
[Root] Car(
color:white,
type:sedan
...
) {
id
seat(type:leather, color:black),
rim(color: blue, shape: OutOfTheWorld){
// nested query
material(hardness: high), // solved `Why no.2`: deep argument.
// More nested
brand(trustWorthy: high) {
priceRange(range: mid),
area,
...
},
id
}
numberOfPassengers,
...
}
现在每个字段都负责其参数和解析器,而不是将所有参数集中到一个根中。
什么时候申请?
每当您发现自己为该字段创建专用解析器时,将参数传递给该字段(不是根,更糟的是:信息)
我正在使用 apollo-server 和 apollo-graphql-tools,我有以下架构
type TotalVehicleResponse {
totalCars: Int
totalTrucks: Int
}
type RootQuery {
getTotalVehicals(color: String): TotalVehicleResponse
}
schema {
query: RootQuery
}
Resolver函数是这样的
{
RootQuery: {
getTotalVehicals: async (root, args, context) => {
// args = {color: 'something'}
return {};
},
TotalVehicleResponse: {
totalCars: async (root, args, conext) => {
// args is empty({}) here
.........
.........
},
totalTrucks: async (root, args, conext) => {
// args is empty({}) here
.........
.........
}
}
}
}
我的问题是如何在任何子解析器中访问根解析器 (getTotalVehicals
) 中可用的 args
?
args
严格引用查询中对该字段提供的参数。如果您希望子解析器可以使用值,您可以简单地从父解析器 return 它们。
{
RootQuery: {
getTotalVehicles: async (root, args, context) => {
return { color: args.color };
},
TotalVehicleResponse: {
totalCars: async (root, args, context) => {
// root contains color here
},
totalTrucks: async (root, args, context) => {
// root contains color here
}
}
}
}
如果您知道自己正在使用 variables,除了公认的答案之外,还有另一种方法,即使用解析器函数的第四个参数:info
.
此 info
参数在其他字段中包含一个字段 variableValues
。
该字段并不严格包含父级的 args
,但如果您的操作是使用传递给父级解析器的变量执行的,那么您将可以通过所有相关的 info.variableValues 访问它们解析器函数。
因此,如果您的操作是这样调用的,例如:
query GetTotalVehicalsOperation($color: String) {
getTotalVehicals(color: $color) {
totalCars
totalTrucks
}
}
... 变量:{color: 'something'}
您将可以访问来自其他解析器的变量:
{
RootQuery: {
getTotalVehicles: async (root, args, context, info) => {
//info.variableValues contains {color: 'something'}
return {};
},
TotalVehicleResponse: {
totalCars: async (root, args, context, info) => {
//same here: info.variableValues contains {color: 'something'}
},
totalTrucks: async (root, args, context, info) => {
//and also here: info.variableValues contains {color: 'something'}
}
}
}
}
了解更多关于 变量 在 GraphQL 中的使用
请参考这些 link(您可以在 5 分钟内完成这些 link)
https://graphql.org/learn/queries/#operation-name
https://graphql.org/learn/queries/#variables
https://graphql.org/learn/queries/#fragments
https://graphql.org/learn/queries/#using-variables-inside-fragments
您将更加掌握操作名称、变量、片段以及片段内变量的使用。
它将帮助您更多地了解解析器函数的 info 参数。
TLDR:将您的 参数 添加到 字段
(客户端)更改自:
Car(type: $type, materialType: $materialType){
id
material
name
...
}
(客户端)收件人:
Car(type: $type){
id,
material(materialType: $materialType) // moved here
name
...
}
然后,在您的服务器 fieldResolver
中访问您的参数(在本例中为 material
字段)。
更长的版本
尽量不要通过 root
传递您的参数,除了 IDs
、arguments that is not from client
或 a parent object
,其他任何使用 字段级参数 (除非你有非常好的理由不)
为什么?
有几个原因:
紧耦合
它会导致耦合并且很难扩展模式 - 来自评论区的@Bruno Ribeiro:
难以排除故障
一个级别还是可以的,但是当你公司的某个人找到了一种方法将论点深入到根源时,很难调试它是如何丢失的。
向children
泄露不必要的信息通过 root 传递参数也意味着传递给每个其他 child,无论是否需要。
混淆了parentobject和参数
您的 parent object 可能与参数具有相同的 属性 键,例如:
offset
,通过提供另一个偏移量,您可能会得到不希望的结果。
如何?
一个简单的查询可以由此增长:
[Root] Car(
color:white,
type:sedan,
seat:leather
) {
id,
seat,
numberOfPassengers,
...
}
为此:
[Root] Car(
color:white,
type:sedan,
seat:leather,
seatColor:black,
rimColor: blue,
rimShape: OutOfTheWorld,
...
) {
id,
seat,
numberOfPassengers,
...
}
您可以这样做,而不是四处传递参数
[Root] Car(
color:white,
type:sedan
...
) {
id
seat(type:leather, color:black),
rim(color: blue, shape: OutOfTheWorld){
// nested query
material(hardness: high), // solved `Why no.2`: deep argument.
// More nested
brand(trustWorthy: high) {
priceRange(range: mid),
area,
...
},
id
}
numberOfPassengers,
...
}
现在每个字段都负责其参数和解析器,而不是将所有参数集中到一个根中。
什么时候申请?
每当您发现自己为该字段创建专用解析器时,将参数传递给该字段(不是根,更糟的是:信息)