Apollo GraphQL 一次查询中的多个 ID 变量

Posted

技术标签:

【中文标题】Apollo GraphQL 一次查询中的多个 ID 变量【英文标题】:Apollo GraphQL multiple ID variables in one query 【发布时间】:2021-06-17 22:49:15 【问题描述】:

我想知道是否可以将多个 ID 传递给 useQuery 用于 apollo 钩子。或者每个 ID 运行一个查询,如果是这样,我将如何去做。

我有以下问题

const DECOR_SHEET = gql`
  query GetDecorSheet($id: ID!) 
    findDecorSheetByID(id:$id)
      refIdArray
      sheetName
      _id
    
  
`;

还有下面useQuery钩子

const  loading, error, data: sheetData  = useQuery(DECOR_SHEET, 
    variables:  id: id ,
    context: 
      headers: 
        authorization: cookieBearer,
      ,
    ,
  );

我有以下 ID 293164663883956749, 293526016787218952,我想返回到一个对象中以便渲染到一个组件中。

我正在使用 Fauna DB,这是输入的 graphQL 架构

type Catalog 
  decor: Boolean
  clothing: Boolean
  supplies: Boolean
  furniture: Boolean
  owner: User


type Decor 
  description: String
  pieces: Int
  purchaser: String
  alterations: Boolean
  cost: Int
  purchaseDate: Date
  category: String
  image: String
  itemNum: Int
  owner: User!
  visible: Boolean


type DecorSheet 
  sheetName: String
  refIdArray: String
  owner: User!


type User 
  email: String! @unique
  catalog: Catalog
  decor: [Decor!] @relation
  decorSheet: [DecorSheet!] @relation


这是生成的架构

directive @embedded on OBJECT
directive @collection(name: String!) on OBJECT
directive @index(name: String!) on FIELD_DEFINITION
directive @resolver(
  name: String
  paginated: Boolean! = false
) on FIELD_DEFINITION
directive @relation(name: String) on FIELD_DEFINITION
directive @unique(index: String) on FIELD_DEFINITION
type Catalog 
  _id: ID!
  decor: Boolean
  clothing: Boolean
  supplies: Boolean
  owner: User
  furniture: Boolean
  _ts: Long!


input CatalogInput 
  decor: Boolean
  clothing: Boolean
  supplies: Boolean
  furniture: Boolean
  owner: CatalogOwnerRelation


input CatalogOwnerRelation 
  create: UserInput
  connect: ID
  disconnect: Boolean


scalar Date

type Decor 
  purchaseDate: Date
  visible: Boolean
  image: String
  description: String
  _id: ID!
  alterations: Boolean
  cost: Int
  pieces: Int
  category: String
  owner: User!
  purchaser: String
  itemNum: Int
  _ts: Long!


input DecorInput 
  description: String
  pieces: Int
  purchaser: String
  alterations: Boolean
  cost: Int
  purchaseDate: Date
  category: String
  image: String
  itemNum: Int
  owner: DecorOwnerRelation
  visible: Boolean


input DecorOwnerRelation 
  create: UserInput
  connect: ID


type DecorPage 
  data: [Decor]!
  after: String
  before: String


type DecorSheet 
  refIdArray: String
  _id: ID!
  sheetName: String
  owner: User!
  _ts: Long!


input DecorSheetInput 
  sheetName: String
  refIdArray: String
  owner: DecorSheetOwnerRelation


input DecorSheetOwnerRelation 
  create: UserInput
  connect: ID


type DecorSheetPage 
  data: [DecorSheet]!
  after: String
  before: String


scalar Long

type Mutation 
  updateUser(
    id: ID!
    data: UserInput!
  ): User
  createUser(data: UserInput!): User!
  createDecorSheet(data: DecorSheetInput!): DecorSheet!
  createDecor(data: DecorInput!): Decor!
  deleteCatalog(id: ID!): Catalog
  updateCatalog(
    id: ID!
    data: CatalogInput!
  ): Catalog
  updateDecor(
    id: ID!
    data: DecorInput!
  ): Decor
  updateDecorSheet(
    id: ID!
    data: DecorSheetInput!
  ): DecorSheet
  deleteDecor(id: ID!): Decor
  deleteUser(id: ID!): User
  createCatalog(data: CatalogInput!): Catalog!
  deleteDecorSheet(id: ID!): DecorSheet


type Query 
  findUserByID(id: ID!): User
  findCatalogByID(id: ID!): Catalog
  findDecorByID(id: ID!): Decor
  findDecorSheetByID(id: ID!): DecorSheet


scalar Time

type User 
  catalog: Catalog
  email: String!
  _id: ID!
  decor(
    _size: Int
    _cursor: String
  ): DecorPage!
  decorSheet(
    _size: Int
    _cursor: String
  ): DecorSheetPage!
  _ts: Long!


input UserCatalogRelation 
  create: CatalogInput
  connect: ID
  disconnect: Boolean


input UserDecorRelation 
  create: [DecorInput]
  connect: [ID]
  disconnect: [ID]


input UserDecorSheetRelation 
  create: [DecorSheetInput]
  connect: [ID]
  disconnect: [ID]


input UserInput 
  email: String!
  catalog: UserCatalogRelation
  decor: UserDecorRelation
  decorSheet: UserDecorSheetRelation

有一个使用 Fauna 的 FQL 进行查询的选项,它可能有一种查询多个 ID 的方法,我将不得不对此进行研究,但如果可能的话,我更愿意在 graphQL 中使用 apollo 进行此操作。

提前感谢

【问题讨论】:

总是只有两个吗? 【参考方案1】:

如果它总是恰好是两个 id,您可以使用字段别名轻松地在单个查询中获取两个对象:

const DECOR_SHEET = gql`
  query GetDecorSheet($firstId: ID!, $secondId: ID!) 
    firstDecorSheet: findDecorSheetByID(id: $firstId) 
      refIdArray
      sheetName
      _id
    
    secondDecorSheet: findDecorSheetByID(id: $secondId) 
      refIdArray
      sheetName
      _id
    
  
`;

【讨论】:

不,它并不总是只有两个,不幸的是它改变了 那么您要么需要动态构建查询文档(这有点难看,但可能),或者确实需要查看 Faunadb 选项,这些选项将改变架构以提供具有多个装饰表的列表字段通过 id 列表。单独使用 Apollo 无济于事 - 为了提高效率,您的服务器需要提供专用的解析器。 我将联系动物支持并查看那里的文档,看看我是否能找到一种方法来创建一个允许将 ID 列表作为查询传递的模式。谢谢你的兴趣,我将如何进行这个动态查询,我是否会以某种方式循环查询,它是一个钩子,所以它会抱怨被放入一个循环中,我很确定。 我的意思是一个 useQuery 钩子,但是使用我的答案中的别名技术传递一个具有动态字段数的查询文档。 找到了一个动物解决方案并发布在下面。【参考方案2】:

感谢 FaunaDB 的支持

以下查询和 UDF 可以解决问题

查询

type Query 
  getMultipleDecors(DecorId: [ID!]): [Decor]
    @resolver(name: "get_multiple_decors")

udf 命名为get_multiple_decors

Query(
  Lambda(
    ["input"],
    Let(
      
        data: Map(
          Var("input"),
          Lambda("x", Get(Ref(Collection("Decor"), Var("x"))))
        )
      ,
      Var("data")
    )
  )
)

【讨论】:

以上是关于Apollo GraphQL 一次查询中的多个 ID 变量的主要内容,如果未能解决你的问题,请参考以下文章

为多个 vue 属性重用 apollo graphql 查询定义

在 apollo graphql 的单个 useEffect 挂钩中使用多个查询

如何使用 react-apollo 使用相同的查询进行多个 graphql 查询?

使用 Apollo 客户端和 React 的多个查询

Apollo - Angular 应用程序中子组件的多个 graphql 订阅

具有多个别名和 Apollo (Vue.js) 的 GraphQL 查询