简体   繁体   English

GraphQL:在同一查询中使用输入类型及其字段之一

[英]GraphQL: Use input type and one of its fields in the same query

I'm wondering how to use both an input type and one of its fields as arguments in the same GraphQL query.我想知道如何在同一个 GraphQL 查询中将输入类型及其字段之一用作 arguments。 I think there are a few valid solutions, but I'm wondering which (if any) are best practice.我认为有一些有效的解决方案,但我想知道哪些(如果有的话)是最佳实践。

Consider the following hypothetical query.考虑以下假设查询。 We get players by location and status, and team members who are in the same location, but the member field only has a location argument:我们通过位置和状态获取玩家,以及处于同一位置的团队成员,但member字段只有一个location参数:

input PlayerInput {
  location: String!
  status: Int!
}

query getPlayers($playerInput: PlayerInput) {
  players(playerInput: $playerInput) {
    name
    team {
      name
      members(location: ???) { // <-- How to access playerInput.location?
        name
      }
    }
  }
}

I can think of a few ways to solve this:我可以想到几种方法来解决这个问题:

1. Change the query to take individual arguments 1.更改查询取个人arguments

query getPlayers($location: String!, $status: Int!) {
  players(playerInput: { location: $location, status: $status }) {
    name
    team {
      name
      members(location: $location) {
        name
      }
    }
  }
}

2. Update the schema so members takes the right input type 2.更新架构,使members采用正确的输入类型

query getPlayers($playerInput: PlayerInput) {
  players(playerInput: $playerInput) {
    name
    team {
      name
      members(playerInput: $playerInput) { // <-- Requires changing schema
        name
      }
    }
  }
}

This doesn't seem great for a few reasons, and would only work if you have the ability to update the schema.由于某些原因,这看起来不太好,并且只有在您能够更新模式时才有效。

3. Pass location in as a redundant individual argument 3. 将location作为冗余的单个参数传入

query getPlayers($playerInput: PlayerInput, $location: String!) {
  players(playerInput: $playerInput) {
    name
    team {
      name
      members(location: $location) {
        name
      }
    }
  }
}

This seems fine, just that there's some duplication when creating the query:这看起来不错,只是在创建查询时有一些重复:

const location = 'US';
const status = 1;

fetch({
  query: getPlayersQuery,
  variables: {
    location,
    playerInput: {
      location,
      status,
    }
  }
})...

Are any of these the preferred way of doing something like this?这些是做这样的事情的首选方式吗? Are there other ways I haven't considered?还有其他我没有考虑过的方法吗?

Utilizing multiple arguments over a single argument that takes an input type (option #1) sometimes makes sense conceptually , but it lacks any other real merit and has the downside of making your variable definitions unnecessarily verbose.在采用输入类型(选项 #1)的单个参数上使用多个 arguments 有时在概念上是有意义的,但它缺乏任何其他真正的优点,并且具有使变量定义不必要地冗长的缺点。 In my opinion, using input types typically enforces typings better as well.在我看来,使用输入类型通常也能更好地强制输入。 Changing your schema just to avoid duplication is not worth it.仅仅为了避免重复而更改模式是不值得的。

Utilizing the same input object type on both fields (option #2) should only be done if both fields actually need all those input fields.在两个字段上使用相同的输入 object 类型(选项 #2)应该仅在两个字段实际上需要所有这些输入字段时才执行。 Doing it just to avoid duplication is a bad idea -- it effectively introduces inputs that are unused, which is not a good experience for any other developer consuming the API.这样做只是为了避免重复是一个坏主意——它有效地引入了未使用的输入,这对于使用 API 的任何其他开发人员来说都不是一个好的体验。

Option #3 is fine.选项#3 很好。 It also puts the ball in the front end dev's court -- if they wanted to avoid the duplication, they could also just as easily do this without you introducing additional arguments:它还将球放在前端开发人员的法庭上——如果他们避免重复,他们也可以轻松地做到这一点,而无需您引入额外的 arguments:

query getPlayers($status: Int!, $location: String!) {
  players(playerInput: { status: $status, location: $location }) {
    name
    team {
      name
      members(location: $location) {
        name
      }
    }
  }
}

However, the duplication is most likely actually a good thing.然而,重复很可能实际上是一件好事。 You don't encounter these scenarios too much in the wild because we're dealing with graphs of data.你不会在野外遇到太多这些场景,因为我们正在处理数据 The players , team and members fields are all part of a hierarchy, where the parent field constrains the data returned by the child -- for example, members doesn't return all members, just members of that particular team. playersteammembers字段都是层次结构的一部分,其中父字段约束子字段返回的数据——例如, members不返回所有成员,只返回特定团队的成员。 That means, in most cases if you constrain players to only include data from a particular location, you're also constraining the data returned by child fields like members .这意味着,在大多数情况下,如果您限制players仅包含来自特定位置的数据,那么您也会限制由子字段(如members )返回的数据。 If you feel like members needs its own location argument, then that implies that the two location inputs could be different .如果您觉得members需要自己的location参数,那么这意味着两个位置输入可能不同 If they could be different, they should be represented as two separate variables to maximize flexibility and query reuse.如果它们可能不同,则应将它们表示为两个单独的变量,以最大限度地提高灵活性和查询重用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM