我的架构中有一个名为df.loc[index, :] = new_row
的类型:
Article
对于它的更新,type Article {
id: ID!
updated: DateTime
headline: String
subline: String
}
突变使用了相应的输入类型:
updateArticle(id: ID!, article: ArticleInput!)
突变本身看起来像这样:
input ArticleInput {
headline: String
subline: String
}
文章总是作为一个整体保存(不是逐个单独的字段),因此当我将文章传递给我之前提取的那个变异时,它会抛出mutation updateArticle($id: ID!, $article: ArticleInput!) {
updateArticle(id: $id, article: $article) {
id
updated
headline
subline
}
}
,{{1}之类的错误}和Unknown field. In field "updated"
。这些有根本原因,那些字段没有在输入类型上定义。
根据spec:
,这是正确的行为(...)此无序地图不应包含任何名称不包含的条目 由此输入对象类型的字段定义,否则为错误 应该被抛出。
现在我的问题是处理这些场景的好方法是什么。我应该将应用代码中输入类型允许的属性列入白名单吗?
如果可能的话,我想避免这种情况,并且可能有一个实用程序功能将它们切换为我,它知道输入类型。但是,由于客户端不了解架构,因此必须在服务器端进行。因此,不必要的属性将被转移到那里,我想这是他们不应该首先转移的原因。
有没有比白名单更好的方式?
我正在使用Unknown field. In field "__typename"
,Unknown field. In field "id"
和apollo-client
。
答案 0 :(得分:6)
因此,我能想到的最优雅的方法是使用查询片段,其中包括数据的所有可变字段。 {1}} filter utility可以使用该片段在发生突变之前删除所有不需要的数据。
要点是:
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)}})
})
})
...
片段现在也可以重复用于创建新文章。
答案 1 :(得分:0)
我个人也有相同的想法,并且较早采用@amann的方法,但是一段时间之后,在输入类型上使用查询片段的概念缺陷就变得明显了。您将无法选择对象类型(对应)中不存在的输入类型字段-甚至还有吗?
当前,我正在通过typesafe-joi
模式描述我的输入数据,并使用它的stripUnknown
选项来过滤出我的表单数据。
无效数据永远不会离开表格,因此可以静态键入有效数据。
从某种意义上说,创建joi模式与定义“输入片段”是相同的活动,因此不会发生代码重复,并且您的代码可以是类型安全的。