自定义标量类型的输入参数未调用`parseValue`

时间:2019-12-11 22:21:36

标签: node.js graphql apollo

我定义了这样的模式:

const query = new GraphQLObjectType({
    name: 'Query',
    fields: {
      quote: {
        type: queryType,
        args: {
          id: { type: QueryID }
        },
      },
    },
  });
const schema = new GraphQLSchema({
    query,
  });

QueryID是自定义的标量类型。

const QueryID = new GraphQLScalarType({
  name: 'QueryID',
  description: 'query id field',
  serialize(dt) {
    // value sent to the client
    return dt;
  },
  parseLiteral(ast) {
    if (ast.kind === 'IntValue') {
      return Number(ast.value);
    }
    return null;
  },
  parseValue(v) {
    // value from the client
    return v;
  },
});

客户查询

query {
   quote(queryType: 1)
}

我发现客户端向我的服务器发送查询时未调用parseValue方法。我可以看到parseLiteral被正确调用。 在我可以找到的大多数文档中,它们使用gql定义架构,并且需要在其架构定义中放入scalar QueryID。但就我而言,我正在使用GraphQLSchema对象作为架构。这是根本原因吗?如果是,那么使其最佳工作方式是什么?我不想切换到gql格式,因为我需要在运行时构造模式。

1 个答案:

答案 0 :(得分:0)

serialize仅在响应中将标量发送回客户端时才调用。它作为参数接收的值是解析程序中返回的值(或者,如果解析程序返回了Promise,则该Promise解析为该值)。

parseLiteral仅在解析查询中的 literal 值时被调用。文字值包括字符串("foo",数字(42),布尔值(true)和null。该方法作为参数接收的值是此文字值的AST表示形式。

parseValue仅在解析查询中的变量值时被调用。在这种情况下,该方法从与查询一起提交的variables对象接收相关的JSON值作为参数。

所以,假设这样的模式:

type Query {
  someField(someArg: CustomScalar): String
  someOtherField: CustomScalar
}

序列化:

query {
  someOtherField: CustomScalar
}

parseLiteral:

query {
  someField(someArg: "something")
}

parseValue:

query ($myVariable: CustomScalar) {
  someField(someArg: $myVariable)
}