graphql服务1类型防御系统:
import { gql } from 'apollo-server';
const typeDefs = gql`
type Post {
postId: ID!
postTitle: String!
postContent: String!
postAuthorId: ID
}
input PostTag {
name: String!
}
input PostInput {
postTitle: String!
postContent: String!
postAuthorId: ID!
postTags: [PostTag!]!
}
type CommonResponse {
code: Int!
message: String!
}
type Query {
posts: [Post]!
}
type Mutation {
addPost(post: PostInput): CommonResponse!
}
`;
export { typeDefs };现在,graphql服务2希望从graphql服务1扩展PostTag输入类型,如下所示:
import { gql } from 'apollo-server';
const typeDefs = gql`
extend input PostTag {
color: String
}
`;
export { typeDefs };我打印缝合模式,这是正确的。
enum CacheControlScope {
PUBLIC
PRIVATE
}
type CommonResponse {
code: Int!
message: String!
}
type Mutation {
addPost(post: PostInput): CommonResponse!
}
type Post {
postId: ID!
postTitle: String!
postContent: String!
postAuthorId: ID
}
input PostInput {
postTitle: String!
postContent: String!
postAuthorId: ID!
postTags: [PostTag!]!
}
input PostTag {
name: String!
color: String
}
type Query {
posts: [Post]!
}
"""The `Upload` scalar type represents a file upload."""
scalar Upload但是当客户端发送这样的突变时:
mutation{
addPost(post: {
postTitle: "ez2on",
postContent: "golang",
postAuthorId: "1",
postTags: [{
name: "222",
color: "red"
}]
}){
code
message
}
}得到了这个错误:
{
"errors": [
{
"message": "Variable \"$_v0_post\" got invalid value { postTitle: \"ez2on\", postContent: \"golang\", postAuthorId: \"1\", postTags: [[Object]] }; Field \"color\" is not defined by type PostTag at value.postTags[0].",
"locations": [
{
"line": 7,
"column": 3
}
],
"path": [
"addPost"
],
"extensions": {
"code": "INTERNAL_SERVER_ERROR",
"exception": {
"errors": [
{
"message": "Variable \"$_v0_post\" got invalid value { postTitle: \"ez2on\", postContent: \"golang\", postAuthorId: \"1\", postTags: [[Object]] }; Field \"color\" is not defined by type PostTag at value.postTags[0].",
"locations": []
}
],
"stacktrace": [
"Error: Variable \"$_v0_post\" got invalid value { postTitle: \"ez2on\", postContent: \"golang\", postAuthorId: \"1\", postTags: [[Object]] }; Field \"color\" is not defined by type PostTag at value.postTags[0].",
" at new CombinedError (/Users/ldu020/workspace/github.com/mrdulin/apollo-graphql-tutorial/node_modules/graphql-tools/src/stitching/errors.ts:90:5)",
" at Object.checkResultAndHandleErrors (/Users/ldu020/workspace/github.com/mrdulin/apollo-graphql-tutorial/node_modules/graphql-tools/src/stitching/errors.ts:111:11)",
" at CheckResultAndHandleErrors.transformResult (/Users/ldu020/workspace/github.com/mrdulin/apollo-graphql-tutorial/node_modules/graphql-tools/src/transforms/CheckResultAndHandleErrors.ts:15:12)",
" at /Users/ldu020/workspace/github.com/mrdulin/apollo-graphql-tutorial/node_modules/graphql-tools/src/transforms/transforms.ts:37:45",
" at Array.reduce (<anonymous>)",
" at applyResultTransforms (/Users/ldu020/workspace/github.com/mrdulin/apollo-graphql-tutorial/node_modules/graphql-tools/src/transforms/transforms.ts:35:21)",
" at /Users/ldu020/workspace/github.com/mrdulin/apollo-graphql-tutorial/node_modules/graphql-tools/src/stitching/delegateToSchema.ts:104:12",
" at step (/Users/ldu020/workspace/github.com/mrdulin/apollo-graphql-tutorial/node_modules/graphql-tools/dist/stitching/delegateToSchema.js:31:23)",
" at Object.next (/Users/ldu020/workspace/github.com/mrdulin/apollo-graphql-tutorial/node_modules/graphql-tools/dist/stitching/delegateToSchema.js:12:53)",
" at fulfilled (/Users/ldu020/workspace/github.com/mrdulin/apollo-graphql-tutorial/node_modules/graphql-tools/dist/stitching/delegateToSchema.js:3:58)"
]
}
}
}
],
"data": null
}发布于 2019-07-26 11:56:37
重要的是要记住,makeRemoteExecutableSchema只是“使用提供的链接将请求委托给底层服务”。当您从远程模式查询字段时,它将这些特定字段的请求委托给远程服务器,从而有效地重新路由请求。无论您是用其他的模式缝制模式,还是单独使用它,这都是正确的。
架构拼接允许您组合任意数量的本地和远程架构。但是,任何远程架构仍将由各自的服务器解析其字段。
因为拼接合并了提供的模式的类型定义,所以可以在一个模式中使用extend关键字来修改另一个模式的类型,即使它是一个远程模式。如果我们扩展一个对象类型,我们也可以使用添加一些解析器来帮助解析我们添加的字段。
扩展远程模式的输入对象有点不同。没有“解析”输入对象。相反,我们通过扩展它所做的就是说“这些字段也是有效的”。但是,当我们请求一些将修改后的输入对象作为参数的远程模式字段时,该字段的解析再次被委托给底层远程模式。它获取修改后的输入对象,当它验证它时,它会找到额外的字段并抛出一个错误。
换句话说,不可能像这样扩展输入类型。考虑一下,即使请求没有失败验证--即使您扩展了输入类型,原始解析器也没有被更改,因此无论如何它也不知道如何处理附加的输入类型字段。
注意到:如果您执行上述操作,但是使用了两个本地模式,则扩展应该按照预期的方式工作,因为在本例中没有委托。您仍然保留了一个解析器,它不一定知道如何处理新的输入对象字段。
https://stackoverflow.com/questions/57213157
复制相似问题