无法扩展远程graphql嵌套输入类型

时间:2019-07-26 04:19:37

标签: graphql apollo-server

graphql服务1类型defs:

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
}

1 个答案:

答案 0 :(得分:0)

请记住,makeRemoteExecutableSchema只是“使用[提供的]链接将请求委派给基础服务”,这一点很重要。当您从远程模式查询字段时,它将对这些特定字段的请求委派给远程服务器,从而有效地重新路由了该请求。无论您是将架构与其他架构缝合还是单独使用,都是如此。

模式拼接允许您组合任意数量的本地远程模式。但是,任何远程模式仍将由其各自的服务器解析其字段。

由于针脚合并了提供的模式的类型定义,因此即使是远程模式,也可以在一个模式内使用extend关键字来修改另一个模式的类型。如果我们扩展对象类型,我们也可以add some resolvers来帮助解决我们添加的字段。

扩展远程模式的输入对象有些不同。没有“解析”输入对象。相反,我们通过扩展它所要做的就是说“这些字段也是有效的”。但是,当我们请求将修改后的输入对象作为参数的某个远程模式字段时,该字段的解析将再次委托给基础远程模式。它获取修改后的输入对象,并在对其进行验证时发现额外的字段并引发错误。

换句话说,不可能扩展这样的输入类型。考虑一下,即使请求没有验证失败-即使您扩展了输入类型,原始解析器也没有更改,因此它肯定不知道如何处理附加输入仍然要输入字段。

注意:如果您执行上述操作但使用两个 local 模式,则扩展名应按预期工作,因为在这种情况下没有委派。仍然有一个解析器,它不一定知道如何处理新的输入对象字段。