在GraphQL中删除之前删除不必要的字段

ama*_*ann 7 javascript graphql graphql-js react-apollo apollo-client

我有一个Article在我的架构中调用的类型:

type Article {
  id: ID!
  updated: DateTime
  headline: String
  subline: String
}
Run Code Online (Sandbox Code Playgroud)

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

input ArticleInput {
  headline: String
  subline: String
}
Run Code Online (Sandbox Code Playgroud)

突变本身看起来像这样:

mutation updateArticle($id: ID!, $article: ArticleInput!) {
  updateArticle(id: $id, article: $article) {
    id
    updated
    headline
    subline
  }
}
Run Code Online (Sandbox Code Playgroud)

文章始终保存为一个整体(而不是单个字段逐个),所以当我通过了一篇文章,该突变我以前牵强,它会抛出这样的错误Unknown field. In field "updated",Unknown field. In field "__typename"Unknown field. In field "id".这些有根本原因,那些字段没有在输入类型上定义.

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

(...)此无序映射不应包含任何名称未由此输入对象类型的字段定义的条目,否则应抛出错误.

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

如果可能的话我想避免这种情况,并且可能有一个实用程序功能将它们切换为我,它知道输入类型.但是,由于客户端不了解架构,因此必须在服务器端进行.因此,不必要的属性将转移到那里,我想这是他们不应该首先转移的原因.

有没有比白名单更好的方法?

我正在使用apollo-client,react-apollo而且graphql-server-express.

ama*_*ann 8

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

要点是:

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)}})
  })
})

...
Run Code Online (Sandbox Code Playgroud)

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

  • 他们应该在apollo docs上显示这样的例子. (2认同)