Apollo Server:将参数传递给嵌套解析器

Posted

技术标签:

【中文标题】Apollo Server:将参数传递给嵌套解析器【英文标题】:Apollo Server: pass arguments to nested resolvers 【发布时间】:2020-06-30 11:21:51 【问题描述】:

我的 GraphQL 查询如下所示:


    p1: property(someArgs: "some_value") 
        id
        nestedField 
            id
            moreNestedField 
                id
            
        
    

在服务器端,我使用的是 Apollo Server。 我有property 的解析器和nestedFieldmoreNestedField 的其他解析器。 我需要在嵌套解析器上检索 someArgs 的值。 我尝试使用解析器上可用的context 来做到这一点:

property: (_, someArgs, ctx) => 
    ctx.someArgs = someArgs;

    // Do something

但这不起作用,因为上下文在所有解析器之间共享,因此如果我的查询中有多个 property,则上下文值不会很好。

我还尝试在嵌套解析器上使用info 上的path。我可以进入property 字段,但我没有这里的论点......

我还尝试在 info 上添加一些数据,但它没有在嵌套解析器上共享。

在所有解析器上添加参数不是一种选择,因为它会使查询变得非常臃肿且编写起来很麻烦,我不希望这样。

有什么想法吗?

谢谢!

【问题讨论】:

您可以尝试将参数分配给返回值 - 它应该由嵌套解析器中的父级 [并从响应中过滤掉] 可用 成功了!它对您的解决方案很有魅力。随意写一个正确的答案来获得荣誉;) 【参考方案1】:

您可以像这样通过父字段传递值:

function propertyResolver (parent,  someArgs ) 
  const property = await getProperty()
  property.someArgs = someArgs
  return property


function nestedPropertyResolver ( someArgs ) 
  const nestedProperty = await getNestedProperty()
  nestedProperty.someArgs = someArgs
  return nestedProperty


function moreNestedPropertyResolver ( someArgs ) 
  // do something with someArgs

请注意,这是否可行,它也可能首先表明您的架构设计存在潜在问题。根据您解析这些字段的方式(从数据库中获取它们、向另一个 API 发出请求等),最好采用完全不同的方法——例如,通过预先加载根解析器中的所有内容。但是,如果没有更多上下文,很难提出任何其他建议。

【讨论】:

【参考方案2】:

参数可以使用当前返回的值传递给子解析器。稍后将从响应中删除其他数据。

我将“借用”Daniel 的代码,但没有特定参数 - 将 args 向下传递作为参考(对于更多 args,适合/更清晰/更具可读性):

function propertyResolver (parent, args) 
  const property = await getProperty()
  property.propertyArgs = args
  return property


// if this level args required in deeper resolvers
function nestedPropertyResolver (parent, args) 
  const nestedProperty = await getNestedProperty()
  nestedProperty.propertyArgs = parent.propertyArgs
  nestedProperty.nestedPropertyArgs = args
  return nestedProperty


function moreNestedPropertyResolver (parent) 
  // do something with parent.propertyArgs.someArgs

正如 Daniels 所说,这种方法的功能有限。你可以chain results 并在子解析器中有条件地做一些事情。您将拥有父级和过滤后的子级...未使用子级条件过滤父级(例如在 SQL ... WHERE ... AND ... AND ... 在连接表上),这可以在父级解析器中完成。

【讨论】:

你好,我不知道如何使用这些方法。你有使用这些的代码示例吗?【参考方案3】:

请在此处查看有关如何传递参数的答案: https://***.com/a/63300135/11497165

为了简化它,您可以使用 args 定义字段类型:

在你的类型定义

type Query
  getCar(color: String): Car
  ... other queries


type Car
  door(color: String): Door // <-- added args
  id: ID
  previousOwner(offset: Int, limit: Int): Owner // <-- added args
  ...

然后,在您的客户端查询中(来自 apollo 客户端或您的 gql 查询):

query getCar(carId:'123')
  door(color:'grey') // <-- add variable
  id
  previousOwner(offset: 3) // <-- added variable
  ... other queries

您应该能够在您的子解析器参数中访问颜色:

在您的解析器中:

Car
  door(root,args,context)
   const color = args.color // <-- access your arguments here
  
  previousOwner(root,args,context)
   const offset = args.offset // <-- access your arguments here
   const limit = args.limit // <-- access your arguments here
  
  ...others

你的例子:

会是这样的


    p1: property(someArgs: "some_value")  // <-- added variable
        id
        nestedField(someArgs: "some_value")  // <-- added variable
            id
            moreNestedField(offset: 5) 
                id
            
        
    

【讨论】:

为什么在类型定义上有参数(顶部代码示例)?它们不应该只放在查询定义中(中间代码示例)还是在类型定义中混合解析器和字段(顶部代码示例)?我不明白... @goldenmaza 这是传递参数的方式。您可以将其添加到您的嵌套类型。你可以试试看。它应该工作。而不是将其添加到您的父母退货中。您在类型定义中添加参数。如果有任何困惑,请随时提出任何问题。 谢谢你的帮助...如果我开始我会问太多...现在我只是想了解更多关于 GraphQL 和 Sequelize 以使我的项目更好。在对每种类型进行单独查询之前,现在我尝试嵌套它们并添加参数,这样我就可以减少前端(React)中的代码量以匹配某些实例与另一个实例,幸运的是,查询中的外键和嵌套类型使得容易得多。但是,我当前的源代码没有正确使用参数,因此我在 *** 上发了帖子。 嗨~我已经编辑了答案,试着看看它对你有没有意义,对于你的第二个问题,看看我是否理解正确,你的意思是你加入你所有的猎物和通过父母将其返回给您的子解析器? 不,我做了一个分别具有每种类型的查询,然后将结果返回到前端,然后前端必须根据页面的要求处理不同的数组。不是最好的解决方案,因为它需要几个循环和 if 语句来确定什么属于什么(这是在我添加关联之前)。这些是我现在尝试通过使用嵌套查询来实现的改进。外键已经设置好了,现在我只希望我的解析器(我相信它们应该被使用)返回正确的数据(基于参数)。

以上是关于Apollo Server:将参数传递给嵌套解析器的主要内容,如果未能解决你的问题,请参考以下文章

将参数传递给子节点解析器函数

将参数传递给 react-apollo-hooks useQuery

将参数传递给 apollo 中的查询失败

如何将参数传递给 apollo 中的查询方法?

将参数传递给 React Apollo 突变

如何将 Apollo 数据和 React Router 4 url​​ 参数传递给我的组件