【问题标题】:Deep merging fragments深度合并片段
【发布时间】:2021-04-18 20:41:12
【问题描述】:

我正在使用 GraphQL API(我不拥有它)来访问数据。我广泛使用片段,我不止一次遇到的一个问题是片段似乎没有深度合并。考虑以下查询:

fragment BasicInfo on Person {
    id
    name
    address {
        city
        country
    }
}

query ProfileCard($id: ID) {
    personById(id: $id) {
        ...BasicInfo
        id
        age
        address {
            streetName
            streetNumber
        }
    }
}

在这里,我们运行一个基本查询,以从个人资料卡中获取一些信息,包括此人的年龄和他们的一些地址(街道名称和号码)。配置文件卡使用的另一个组件也需要一些可以在BasicInfo 片段中找到的信息。这包括他们的名字以及他们的城市和国家。

运行此查询会返回一个包含以下字段的对象:idnameageaddress.streetNameaddress.streetNumber

address.cityaddress.country 都丢失了 - 查询似乎没有将片段深度合并,只是在浅层插入。

是否可以强制我的片段进行深度合并?这甚至是预期的行为吗?我是否必须与 API 所有者联系才能更正此问题?

我很难找到说明它应该是一种方式的文档。

【问题讨论】:

  • 什么客户?阿波罗? ....地址是一个单独的实体 - 没有 id,没有地址缓存实体合并
  • @xadm 在客户端使用 Apollo,但我什至没有想到这很重要。我假设片段如何合并将在规范中定义,并在实现中进行相同处理。
  • 啊,只有 API 的问题?在操场上测试过?...我希望数据也可以合并...但不知道片段是如何处理/执行的...如果更早解决(遗憾的是,不能保证字段解析顺序)片段包含地址那么不需要解析地址类型,只有子字段(添加到现有的)......或片段所需的字段第一次合并到info(GraphQLResolveInfo)中的当前字段,但[严重]被以下defs覆盖......我怀疑它(杂项片段和类型字段行为的重叠字段)在规范中定义...有趣的问题,我会问 API 所有者

标签: graphql graphql-fragments


【解决方案1】:

我刚刚在使用@apollo/client 时遇到了类似的问题,有趣的是它也与地址模型有关。我的第二个片段似乎完全被忽视并且没有合并。我在下面写了一个foobar 代码示例:

type Request = {
  id: string
  stops: Array<Stop>
}

type Stop = {
  id: string;
  address: Address;
}

type Address = {
  id: string;
  address1: string;
  name: string;
}

const ROOT_FRAGMENT = gql`
  fragment foo_Request on Request {
    id
    stops {
    ...bar_Stop
    ...qux_Stop
    }
    ${STOP_FRAGMENT_1}
    ${STOP_FRAGMENT_2}
}
`;

const STOP_FRAGMENT_1 = gql`
  fragment bar_Stop on Stop {
    id
    address {
      id
      address1
    }
  }
}
`;

const STOP_FRAGMENT_2 = gql`
  fragment qux_Stop on Stop {
    id
    address {
      id
      name
    }
  }
}
`;

/*

expected: 
{
  id: "request-1"
  stops: [
    {
      id: "stop-1",
      address: {
        id: "address-1",
        address1: "123 my way",
        name: "Home",
      },
    },
  ],
}

actual: 
{
  id: "request-1"
  stops: [
    {
      id: "stop-1",
      address: {
        id: "address-1",
        address1: "123 my way",
      },
    },
  ],
}

*/

【讨论】:

  • 您好,感谢您的贡献! Buuuuut,您可能应该阅读这里的工作方式。您刚刚发布了一个“答案”,但它似乎更像是一个“这也发生在我身上”
【解决方案2】:

尝试改用别名。类似的东西

fragment BasicInfo on Person {
      id
      name
      cityCountryAddress: address {
          city
          country
      }
  }

【讨论】:

    猜你喜欢
    • 2017-09-17
    • 2021-03-13
    • 1970-01-01
    • 2015-05-05
    • 2013-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-12
    相关资源
    最近更新 更多