首页 > 解决方案 > 阿波罗服务器上的自定义标量

问题描述

我试图在阿波罗服务器上定义一个自定义标量,到目前为止,这就是我所拥有的

自定义标量文件 (timestamp.js)

import { isRFC3339 } from 'validator';
import { GraphQLScalarType } from 'graphql';

export default new GraphQLScalarType({
  name: 'Timestamp',
  description: 'RFC3339 Timestamp format',
  serialize(value) {
    if (isRFC3339(value)) {
      return value;
    }
    throw new Error('Timestamp cannot represent an invalid RFC-3339 Timestamp string');
  },
  parseValue(value) {
    if (isRFC3339(value)) {
      return value;
    }
    throw new Error('Timestamp cannot represent an invalid RFC-3339 Timestamp string');
  },
  parseLiteral(ast) {
    if (isRFC3339(ast.value)) {
      return ast.value;
    }
    throw new Error('Timestamp cannot represent an invalid RFC-3339 Timestamp string');
  }
});

在我的架构中,我的架构位于多个文件中,但我在将它们传递给 makeExecutableSchema 之前将它们连接在一起。

scalar Timestamp

在具有稍后导出的 makeExecutableSchema 文件和我的服务器构造函数中的用户。

import timeStamp from './scalars/timeStamp';
.
.
.
.
const schema = {
  typeDefs: [
    myTypeDefs
  ],
  resolvers: merge(
    resolvers,
    timeStamp
  ),
};

export default makeExecutableSchema({
  typeDefs: schema.typeDefs,
  resolvers: schema.resolvers
});

我不知道我错过了什么,因为我在尝试运行我的 API 时遇到了这个错误

throw new _1.SchemaError("\"" + typeName + "\" defined in resolvers, but has invalid value \"" + resolverValue + "\". A resolver's value " +
            ^

Error: "name" defined in resolvers, but has invalid value "Timestamp". A resolver's value must be of type object or function.

任何帮助将不胜感激。提前致谢!

标签: graphqlapollo-server

解决方案


使用apollo-server(or graphql-tools) 构建模式时,resolvers参数必须是一个对象,其属性是

  • 架构中输出对象类型的名称
  • (自定义)标量类型的名称
  • 枚举类型的名称

换句话说,生成的对象应该类似于:

const resolvers = {
  Query: {
    // field resolvers here...
  },
  // Maybe some other object types here...
  Timestamp: timeStamp,
}

请注意,对于我们的自定义标量,属性名称需要与我们为标量指定的名称相匹配。这也是您在typeDefs. 在这种情况下,属性将是Timestamp,我们将其设置为GraphQLScalarType我们实例化的。

因此,假设您的实际resolvers变量格式正确,您需要执行以下操作:

merge(
  resolvers,
  { Timestamp: timeStamp }
)

或者,您也可以更改时间戳的默认导出...

export default { Timestamp: new GraphQLScalarType(...) }

或者干脆放弃merge使用扩展语法:)

resolvers: {
  ...resolvers,
  Timestamp: timeStamp,  
}

推荐阅读