简体   繁体   English

GraphQL / Apollo服务器指令导致架构错误

[英]GraphQL / Apollo Server Directives leading to schema error

I'm trying to add directives into our GraphQL API and am following this example, https://www.apollographql.com/docs/apollo-server/features/creating-directives.html#Uppercasing-strings , however, I keep getting the server error (without the directive the server works!): 我正在尝试将指令添加到我们的GraphQL API中,并遵循以下示例: https: //www.apollographql.com/docs/apollo-server/features/creating-directives.html#Uppercasing-strings,但是,我一直在获取服务器错误(如果没有该指令,服务器将正常工作!):

** Uncaught Error: Duplicate schema type name Integer **
    at home/node_modules/apollo-server-core/node_modules/graphql-tools/dist/schemaVisitor.js:243:27
    at home/node_modules/apollo-server-core/node_modules/graphql-tools/dist/schemaVisitor.js:527:9
    at Array.forEach (<anonymous>)
    at each (home/node_modules/apollo-server-core/node_modules/graphql-tools/dist/schemaVisitor.js:526:32)
    at heal (home/node_modules/apollo-server-core/node_modules/graphql-tools/dist/schemaVisitor.js:234:13)
    at healSchema (home/node_modules/apollo-server-core/node_modules/graphql-tools/dist/schemaVisitor.js:225:5)
    at Function.SchemaDirectiveVisitor.visitSchemaDirectives (home/node_modules/apollo-server-core/node_modules/graphql-tools/dist/schemaVisitor.js:474:9)
    at Object.makeExecutableSchema (home/node_modules/apollo-server-core/node_modules/graphql-tools/dist/makeExecutableSchema.js:54:48)
    at new ApolloServerBase (home/node_modules/apollo-server-core/dist/ApolloServer.js:142:43)
    at new ApolloServer (home/node_modules/apollo-server-express/dist/ApolloServer.js:44:1)

The schema is very large so I can't post it here, however, the schema type 'Integer' has not been duplicated. 模式非常大,因此无法在此处发布,但是模式类型'Integer'尚未重复。 I've followed multiple different guides but keep running into this error. 我遵循了多个不同的指南,但一直遇到此错误。

We are using Apollo Server 2.1.0 & GraphQL 14.0.2 我们正在使用Apollo Server 2.1.0和GraphQL 14.0.2

Server setup: 服务器设置:

class error_extension extends GraphQLExtension {
  willSendResponse(o) {
    const { context, graphqlResponse } = o;

    context.add_additional_error_reporting(graphqlResponse.errors);

    return o;
  }
}


// Create (or import) a custom schema directive
class UpperCaseDirective extends SchemaDirectiveVisitor {
  visitFieldDefinition(field) {
    const { resolve = defaultFieldResolver } = field;
    field.resolve = async function (...args) {
      const result = await resolve.apply(this, args);
      if (typeof result === 'string') {
        return result.toUpperCase();
      }
      return result;
    };
  }
}


// Server settings
const server = new ApolloServer({
  typeDefs,
  resolvers,
  schemaDirectives: {
    upper: UpperCaseDirective,
  },
  context: async ({ req, res }) => {
    // some auth logic here - removed for the purpose of this

    return {
      add_additional_error_reporting(errors) {
        if (!errors) return;

        errors = errors.map(item => {

          // add request data to the returned error
          if (`extensions` in item && item.extensions !== undefined)
            item.extensions.request_details = req.body;

          return item;
        });

        return errors;
      },
      req,
      res
    };
  },
  extensions: [() => new error_extension()],
  validationRules: [

    depthLimit(5),

    costAnalysis({ // GraphQL Query Cost 
      maximumCost: 100, // maximum cost of a single  query
      defaultCost: 1, // default cost of a field
      onComplete: (async request_cost => {
        // Callback function to retrieve the determined query cost. It will be invoked whether the query is rejected or not. 
        // This can be used for logging or to implement rate limiting (for example, to store the cost by session and define a max cost the user can have in a specific time).
        try { 
          cost_data = await helper.run_connector_cost_logic(request_cost);
        } catch (err) { throw err; }
      }),
      createError: (maximumCost, cost) => {
        // Function to create a custom error
        throw new ApolloError(`The maximum cost per request is ${maximumCost} however this request is greater than this limit, with a cost of ${cost}.`, `EXCEEDED_MAX_REQ_COST`);
      }
    })

  ],
  formatError: err => { 
    console.error(err); // eslint-disable-line
    return err; 
  },
  formatResponse: res => {
    res.extensions.cost = cost_data;

    // wipe the cost data for the next request
    cost_data = {};

    return res;
  },
  introspection: false,
  tracing: false,
  debug: false
});

Any help would be appreciated! 任何帮助,将不胜感激!

This was an issue with our Scalars which are generated using JS logic however one statement was flawed leading to multiple Scalars with the same name value. 这是使用JS逻辑生成的Scalars的一个问题,但是一个语句存在缺陷,导致多个具有相同名称值的Scalars。

For anyone else, as @Daniel Rearden said in the comments "The error is coming from graphql-tools. That validation logic doesn't get called unless you include directives" hence why the error has only just showen up ie it was nothing related to directives. 对于其他任何人,就像@Daniel Rearden在评论中说的那样:“该错误来自graphql-tools。除非您包含指令,否则不会调用该验证逻辑”,因此为什么只显示该错误,即与该错误无关指令。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM