创建GraphQl请求以获取输入列表

时间:2019-08-01 04:58:59

标签: graphql graphql-java

我有一个查询,希望在不同输入的列表上运行。如何在单个查询请求中执行此操作?

我的查询如下:

QuerySingle

query($personId:ID!, $vehicleId: ID!) {
  person(personID: $personId) {
    name,
    gender,
    hairColor
  },
  vehicle(id: $vehicleId) {
      name,
      model,
      vehicleClass,
  }
}

和参数类似

  { "personId": 1, "vehicleId": "dmVoaWNsZXM6NA==" }

这对于单个输入运行良好。 Single Input Example

但是我想在我喜欢的输入列表上运行它:

[
  { "personId": 1, "vehicleId": "dmVoaWNsZXM6NA==" },
  { "personId": 2, "vehicleId": "dmVoaWNsZXM6Ng==" },
  { "personId": 3, "vehicleId": "dmVoaWNsZXM6Nw==" },
  { "personId": 4, "vehicleId": "dmVoaWNsZXM6OA==" },
  { "personId": 5, "vehicleId": "dmVoaWNsZXM6MTQ=" },
  { "personId": 6, "vehicleId": "dmVoaWNsZXM6MTY=" },
  { "personId": 7, "vehicleId": "dmVoaWNsZXM6MTg=" },
  { "personId": 8, "vehicleId": "dmVoaWNsZXM6MTk=" },
  { "personId": 9, "vehicleId": "dmVoaWNsZXM6MjA=" },
  { "personId": 10, "vehicleId": "dmVoaWNsZXM6MjQ=" }
]

我该怎么做?

一种可以在人和车辆上使用别名并提供不同输入作为不同变量名称的方法。 Example Query with different var aliases

QueryMultiUsingAlias

query($personId_1:ID!, $vehicleId_1: ID!,$personId_2:ID!, $vehicleId_2: ID!) {
  person1: person(personID: $personId_1) {
    ...personData
  },
  vehicle1: vehicle(id: $vehicleId_1) {
     ...vehicleData
  }
  person2: person(personID: $personId_2) {
    ...personData
  },
  vehicle2: vehicle(id: $vehicleId_2) {
     ...vehicleData
  }
}

fragment vehicleData on Vehicle {
    name,
  model,
  vehicleClass
}


fragment personData on Person {
  name,
  gender,
  hairColor
}

参数:

{
  "personId_1": 1,
  "vehicleId_1": "dmVoaWNsZXM6NA==",
  "personId_2": 2,
  "vehicleId_2": "dmVoaWNsZXM6Ng=="
}

我的问题是:

  1. 由于每个输入添加了更多不同类型的数据,因此该查询变得过于粗糙且难以扩展。或添加更多数量的输入参数。有没有更干净的方法来表示此查询?

  2. 如果没有其他方法,graphql-java中是否有功能可根据输入长度从 QuerySingle 生成 QueryMultiUsingAlias

1 个答案:

答案 0 :(得分:0)

首先,我首先考虑将“车辆类型”设置为“人”上的一个字段(似乎和“车辆映射到人”之间存在关系)。然后,您可以按以下方式定义架构:

type Vehicle {
  // fields defining Vehicle type
}

type Person {
    vehicle: Vehicle
    //other fields defining Person type
}

Query {
  person(personId: Int, vehicleId: Int): Person
}

您的解析器可以遵循类似的实现:

Query {
  async person(obj, args, context, info) {
     return await context.db.loadPersonByID(args.personId)
  }
}, 
Person {
  async vehicle(obj, args, context, info) {
    return await context.db.loadVehicleByID(args.vehicleId)
 }
}

或者,如果您的人员db查询的结果包含vehicleId作为属性,则在解析车辆时应该可以从“ obj”参数访问vehicleId,从而无需在查询中使用vehicleId参数(尽管目前尚不清楚)。

最后,与其传递参数数组并修改图形输入模式,不如使用该参数数组从客户端触发多个离散异步查询并等待所有离散变量的异步处理,这是最干净的方法使用Promise.all([query1,query2,etc.])或同等学历的请求。每个查询都会从您的数组中传递personId和vehicleId(假设根据上述指导,甚至仍然需要vehicleId)。您可以按照以下方式在js中映射数组:

const queryResults = await Promise.all(argumentArray.map(async ({personId, vehicleId }) {
     return await // fire query using personId and vehicleId
  }))
}