GraphQL 不调用自定义标量方法

GraphQL not calling custom scalar methods

与其他许多人一样,我正在尝试使用 GraphQL 和 JavaScript 创建自己的 Date 标量。我已经阅读了很多示例并特别遵循 this guide from apollo

我做了什么

这应该使我的 Date 准备好根据我读过的内容使用。但是,我每次执行查询时得到的值与我存储在数据库中的值完全相同。如果那是一个字符串,我会看到一个字符串,如果那是一个数字,我会看到一个数字。它在任何时候都不会被解析或序列化。

这是我的文件的样子。

schema.js

const { buildSchema } = require('graphql');

const schema = buildSchema(`
  scalar Date

  # more schema
`);

module.exports = schema;

root.js

const { dateScalar } = require('./customScalars');

const root = {
  // queries

  // mutations

  // scalars
  Date: dateScalar
};

module.exports = root;

customScalars.js

const { GraphQLScalarType } = require('graphql');

const dateScalar = new GraphQLScalarType({
  name: 'Date',
  description: 'This is a scalar version of the js Date',
  serialize(value) {
    console.log('call serialize');
    return value.getTime();
  },
  parseValue(value) {
    console.log('call parseValue');
    return new Date(value).getFullYear();
  },
  parseLiteral(ast) {
    console.log('call parseLiteral');
    return;
  }
});

module.exports = {
  dateScalar
};

server.js

const express = require('express');
const graphqlHTTP = require('express-graphql');

const schema = require('./graphql/schema.js');
const graphqlRoot = require('./graphql/root.js');

var app = express();
app.use('/endpoint', graphqlHTTP({
  schema: schema,
  graphiql: true,
  rootValue: graphqlRoot,
}));

app.listen(3333, () => console.log('Now browse to localhost:3333/endpoint'));

到目前为止我的调试

从根本上看,它似乎从未将我的架构中的标量与我的自定义标量实例相关联。也许我在这里做错了什么?

我的猜测是 GraphQL 正在使用 .toString() 进行序列化和解析,因为它没有找到我对 serializing/parsing.

的实现

关于如何让 GraphQL 使用我的自定义标量有什么想法吗?

tl;博士

使用 graphql-tools 制作可执行模式并使用 apollo-server-express 而不是 express-graphql


很遗憾,我不熟悉 express-graphql。所以我的解决方案需要用 apollo-server-express 替换它。幸运的是,它不需要太多更改。

我做了一些修改以匹配您的代码,这对我有用。

首先安装软件包: npm install apollo-server-express graphql-tools

代码如下:

const {makeExecutableSchema} = require('graphql-tools')
const {graphqlExpress} = require('apollo-server-express');

const graphqlRoot = require('./graphql/root.js');

//...

const schemaDef = `
  scalar Date

  # more schema
`;

//build the schema
const schema = makeExecutableSchema({
  typeDefs: [schemaDef],
  resolvers: graphqlRoot
});

// your new endpoint:
app.use('/endpoint', bodyParser.json(), graphqlExpress({ schema }));

阅读更多关于 Adding a GraphQL endpoint

此外,使用 Apollo 可以轻松拥有多个模式文件和解析器文件,而不必担心手动组合它们。这是文档中的解释:Modularizing the schema