在 GraphQL 突变之前删除不必要的字段 [英] Remove unnecessary fields before mutation in GraphQL

查看:26
本文介绍了在 GraphQL 突变之前删除不必要的字段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的架构中有一个名为 Article 的类型:

I've got a type called Article in my schema:

type Article {
  id: ID!
  updated: DateTime
  headline: String
  subline: String
}

对于它的更新,有一个由 updateArticle(id: ID!, article: ArticleInput!) 突变使用的相应输入类型:

For updates to it, there's a corresponding input type that is used by a updateArticle(id: ID!, article: ArticleInput!) mutation:

input ArticleInput {
  headline: String
  subline: String
}

突变本身看起来像这样:

The mutation itself looks like this:

mutation updateArticle($id: ID!, $article: ArticleInput!) {
  updateArticle(id: $id, article: $article) {
    id
    updated
    headline
    subline
  }
}

文章总是作为一个整体保存(而不是一个接一个的单个字段),因此当我将文章传递给我之前获取的那个突变时,它会抛出类似 Unknown 字段的错误.在字段更新" 中,未知字段.在字段__typename"Unknown 字段中.在字段id" 中.这些具有根本原因,即这些字段未在输入类型上定义.

The article is always saved as a whole (not individual fields one by one) and so when I pass an article to that mutation that I've previously fetched, it throws errors like Unknown field. In field "updated", Unknown field. In field "__typename" and Unknown field. In field "id". These have the root cause, that those fields aren't defined on the input type.

根据规范,这是正确的行为:

This is correct behaviour according to the spec:

(...) 这个无序映射不应该包含任何名称不属于由该输入对象类型的字段定义,否则报错应该扔掉.

(…) This unordered map should not contain any entries with names not defined by a field of this input object type, otherwise an error should be thrown.

现在我的问题是处理这些场景的好方法是什么.我应该在我的应用代码中列出输入类型允许的所有属性吗?

Now my question is what a good way to deal these kinds of scenarios is. Should I list all properties that are allowed on the input type in my app code?

如果可能的话,我想避免这种情况,并且可能有一个实用函数为我将它们切掉,它知道输入类型.但是,由于客户端不知道架构,这必须在服务器端发生.因此,不必要的属性会转移到那里,我想这就是为什么它们不应该首先转移的原因.

If possible I'd like to avoid this and maybe have a utility function slice them off for me which knows about the input type. However, since the client doesn't know about the schema, this would have to happen on the server side. Thus, the unnecessary properties would be transferred there, which I suppose is the reason why they shouldn't be transferred in the first place.

还有比维护属性列表更好的方法吗?

Is there a better way than maintaining a list of properties?

我正在使用 apollo-clientreact-apollographql-server-express.

I'm using apollo-client, react-apollo and graphql-server-express.

推荐答案

所以我能想到的最优雅的方法是使用片段进行查询,其中包括数据的所有可变字段.该片段可以被 graphql-anywhere过滤器工具 使用> 在突变发生之前删除所有不需要的数据.

So the most elegant way I could think of is using a fragment for the query, which includes all mutable fields of the data. That fragment can be used by the filter utility of graphql-anywhere to remove all unwanted data before the mutation happens.

要点是:

const ArticleMutableFragment = gql`
fragment ArticleMutable on Article {
  headline
  subline
  publishing {
    published
    time
  }
}
`

const ArticleFragment = gql`
fragment Article on Article {
  ...ArticleMutable
  id
  created
  updated
}
${ArticleMutableFragment}
`;

const query = gql`
query Article($id: ID!) {
  article(id: $id) {
    ...Article
  }
}
${ArticleFragment}
`;

const articleUpdateMutation = gql`
mutation updateArticle($id: ID!, $article: ArticleInput!) {
  updateArticle(id: $id, article: $article) {
    ...Article
  }
}
${ArticleFragment}
`;

...

import {filter} from 'graphql-anywhere';

...

graphql(articleUpdateMutation, {
  props: ({mutate}) => ({
    onArticleUpdate: (id, article) =>
      // Filter for properties the input type knows about
      mutate({variables: {id, article: filter(ArticleMutableFragment, article)}})
  })
})

...

ArticleMutable 片段现在也可以重复用于创建新文章.

The ArticleMutable fragment can now also be reused for creating new articles.

这篇关于在 GraphQL 突变之前删除不必要的字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆