在将查询发送到 GraphQL 之前对其进行操作

Posted

技术标签:

【中文标题】在将查询发送到 GraphQL 之前对其进行操作【英文标题】:Manipulate Queries before sending them to GraphQL 【发布时间】:2018-06-20 14:33:56 【问题描述】:

我们使用 apollo-client 和 apollo-server-express 从一个简单的翻译 API 获取数据。

这是当前架构:

type Query 
    translations(language: String!, key: String!): Translation!


type Translation 
    key: String!
    value: String!

还有解析器:

export default 
  Query: 
    translations (obj, args, context, info) 
      return fetchApi('/api/v1/translation', 
        method: 'POST',
        body: JSON.stringify(args)
      )
    
  

在前端应用程序中,我们有一个 React 组件,它在 props 中接收翻译键,然后针对 GraphQL 服务器执行查询:

const translationQuery = gql`
query GetTranslations($language: String!, $key: String!) 
  translations(language: $language, key: $key) 
    value
    key
  
`

现在这会导致 GraphQL 调用每个翻译。我们需要的是累积所有翻译,然后执行 ONE GraphQL 查询。基本上我们希望使用一个接受键列表但仍使用专用翻译组件的查询:

type Query 
    translations(language: String!, keys: [String!]!): Translation!


type Translation 
    key: String!
    value: String!

有没有办法实现我们所需要的?

以下是翻译组件在前端应用程序中的实现方式的简化版本: https://codesandbox.io/s/81n874zjp0

【问题讨论】:

【参考方案1】:

是的,有一个简单的方法

可以将数组作为参数传递给查询。

你可以阅读更多关于"GraphQL - Lists and Non-Null" here

在您的查询操作中,您可以传入一个不可为空的键数组,而不是定义为 $key: String! 的单个 key,例如 $keys: [String!]!

您还需要更新解析器函数以处理键数组并返回单个 TranslationTranslation 数组。

最后,确保更新您的架构。

如果您只执行一次 API 调用并期望得到一个 Translation,它应该如下所示:

type Query 
    translations(language: String!, keys: [String!]!): Translation!


type Translation 
    key: String!
    value: String!

【讨论】:

这对我们来说是不可能的。每个翻译都会生成一个执行查询的 React 组件的新实例 (SomeKey)。这意味着我们无法调整查询以发送数组,因为在执行查询时我们对所有翻译一无所知。我们需要的是在翻译查询发送到 GraphQL 服务器之前对其进行操作/累积,或者在我们获取 API 之前在 GraphQL 服务器上累积它们。 如何让Translation 组件成为由TranslationsContainer 组件管理的受控组件?每个翻译都通过道具获得其价值,并根据任何更改更新TranslationsContainer。这样您就可以在一个地方获取所有翻译键和值,然后使用我提出的解决方案。 抱歉,我不太明白。当您拥有一个受控组件时,您仍然会遇到同样的问题,不是吗?您如何在受控组件中知道在执行查询之前传递了所有键? 您没有提供足够的信息来确定什么对您有用。但是您可以使用的一件事是查询的跳过选项,该选项具有检查您的组件是否已经具有基于组件的道具的所有键的功能。在这里阅读:apollographql.com/docs/react/basics/queries.html#graphql-skip 我设置了我如何实现翻译组件的简化版本。请看看我更新的问题。

以上是关于在将查询发送到 GraphQL 之前对其进行操作的主要内容,如果未能解决你的问题,请参考以下文章

GraphQL 突变“在将标头发送到客户端后无法设置标头”

如何在将图像上传到 Firebase 存储之前对其进行压缩?

如何在将 json 发布到 React 组件状态之前对其进行处理?

如何在将应用发布到 Google Play 之前对其进行测试

在将 HTML 字符串发送到客户端之前格式化 HTML 字符串的 C# 工具[关闭]

如何在 api 服务器中包含字段并在将结果返回到 Graphql 中的客户端之前将其删除