子解析程序中的Graphql访问参数
我正在使用apollo服务器和apollo graphql工具,我有以下模式子解析程序中的Graphql访问参数,graphql,apollo,graphql-js,apollo-server,Graphql,Apollo,Graphql Js,Apollo Server,我正在使用apollo服务器和apollo graphql工具,我有以下模式 type TotalVehicleResponse { totalCars: Int totalTrucks: Int } type RootQuery { getTotalVehicals(color: String): TotalVehicleResponse } schema { query: RootQuery } 解析函数是这样的 { RootQuery: { getTota
type TotalVehicleResponse {
totalCars: Int
totalTrucks: Int
}
type RootQuery {
getTotalVehicals(color: String): TotalVehicleResponse
}
schema {
query: RootQuery
}
解析函数是这样的
{
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
.........
.........
}
}
}
}
我的问题是,如何访问任何子解析程序的根解析程序(
GetTotalDevices
)中可用的args
?args
严格参考该字段查询中提供的参数。如果希望值对子冲突解决程序可用,只需从父冲突解决程序返回即可
{
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
}
}
}
}
如果您知道您正在使用变量,那么除了接受的答案之外,还有另一种方法可以使用解析器函数的第四个参数:
info
此info
参数在其他字段中包含一个字段variableValues
。
此字段不严格包含父级的参数
,但如果您的操作是使用传递给父级冲突解决程序的变量执行的,则您可以通过所有相关冲突解决程序函数的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 请参考这些链接(您可以在5分钟内浏览这些链接) 您将更多地掌握操作名称、变量、片段以及片段中变量的使用 请查看此链接: 它将帮助您了解有关解析程序函数参数的更多信息。将参数添加到字段中 将参数添加到字段(而不是root/info) (客户端) 更改根字段参数
Car(type: $type, materialType: $materialType){
material
id
name
...etc
}
要创建嵌套字段参数,请执行以下操作:
Car(type: $type){
material(materialType: $materialType) // moved from root
id
name
...etc
}
然后,在服务器字段解析器中访问您的参数(material
在本例中为字段)
较长版本
尽量不要通过root/info
传递您的参数,除了IDs
和不是来自客户端的参数之外,其他任何使用字段级参数的都可以(除非您有非常好的理由不)
为什么?
@评论部分的Bruno Ribeiro对此进行了很好的总结:
这会导致耦合,并且很难扩展模式
有几个原因:
当有多个对象访问同一个对象解析器时
很容易错过提供参数的机会,因为所需的参数实际上只有几层。
例如:学生需要bestPal id,它是学校的嵌套字段,如果您通过root提供参数,那么您将把bestPal参数传递给学校并传递给学生。这显然是错误的,因为学校可以有多个学生。每个学生都应该有自己的最好的朋友,所以场地应该在学生身上
此外,将参数添加到根目录并不仅仅是传递给唯一的子目录,而是传递给其他子目录字段。
补偿。如果您的两个孩子需要不同的偏移量。最简单的方法是传递一个不同的命名偏移量,例如:偏移量_1和偏移量_2。为什么不在客户端定义它呢?该参数将仅适用于该字段,且仅适用于该字段
怎么用?
让我们让它变得非常简单:
只有两个层次的论证:
Car(type: $type){
material(materialType: $materialType) // moved from root
id
name
...etc
}
根字段参数
字段级参数
假设您想查询一辆可定制的汽车(现在只限于座椅可定制)
很快你就会发现,你需要定制座椅的颜色
[Root] Car(color:white, type:sedan, seat:leather, seatColor:black)
然后,业务增长,现在我们也可以定制rim:
[Root] Car(color:white, type:sedan, seat:leather, seatColor:black, rimShape:star,rimColor:makeitshine)
接下来是仪表板、排气管、车窗。您已经可以看到它是永无止境的:
要解决这个问题,让我们将其设置为字段级别:
[Root] Car(color:white, type:sedan)
[Field] seat(color: black, texture:fabric)
[Field] rim(shape:star, color: makeitshine)
[Field] window(feature:bulletproof, tint:cantseeme)
......any other thing you want to add
现在,每个字段都负责自己的参数和解析器,而不是将所有参数聚集到一个根中
{
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
}
}
}
}
何时申请?
每当您发现自己正在为该字段创建专用解析程序时,请将参数传递给该字段,而不是通过root(更糟糕的是:info)
示例(针对主持人问题)
本节是回答主持人的问题
(服务器端)
type RootQuery{
getTotalVehicles(颜色:字符串):TotalVehiclerResponse
}
类型TotalVehiclerResponse{
totalCars(颜色:字符串):Int//FYI,这仅在使用变量时有效。因此,依赖信息可能不是一个好主意。谢谢,@Trevor。我更新了我的答案以澄清这一点。请查看此综合链接。请查看此综合链接。也请查看此综合链接。请不要这样做。这会导致解析程序之间的紧密耦合,并且无法很好地扩展。每个esolver应该直接从查询中接收自己的参数。请检查cYee的答案以了解更多信息:这是正确的答案。参数不应该在解析程序之间共享;这会导致耦合,并且很难扩展架构,这样这些链接不会解释如何在解析程序之间共享参数,如OP所要求的。如果您的意图是首先,OP不应该尝试在解析程序之间共享参数,应该在您的答案中加以澄清
// In your child resolver
TotalVehicleResponse{
totalCars(parent, args, ctx){
const {color} = args // <-- access your client args here
return ....
}
totalTrucks(parent, args, ctx){
const {offset, limit} = args // <-- your args from client query
...do db query
return ....
}
}
getTotalVehicles(color: $color){
totalCars(color: $color) <-- add your variable here
totalTrucks(offset: $offset, limit: $limit) <-- add your variable here
}