子解析程序中的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

我正在使用apollo服务器和apollo graphql工具,我有以下模式

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
    }