【问题标题】:GraphQL not calling custom scalar methodsGraphQL 不调用自定义标量方法
【发布时间】:2018-06-30 09:40:17
【问题描述】:

与其他许多人一样,我正在尝试使用带有 JavaScript 的 GraphQL 创建自己的 Date 标量。我读过很多例子,特别关注this guide from apollo

我做了什么

  • 已将 scalar Date 添加到我的架构中
  • 使用我的序列化、parseValue 和 parseLiteral 实现创建了GraphQLScalarType 的实例。我称那个实例为dateScalar
  • 向解析器映射添加了一个名为Date 的新属性,其值为dateScalar

这应该使我的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'));

到目前为止我的调试

  • 我在methodsserialize等上使用过日志,都没有被调用。
  • 我已经从根目录中删除了Date 属性,行为完全一样
  • 我检查了dateScalar 的实例是否符合我的预期。在将其导入不同的文件后,我通过调用console.log(dateScalar.serialize(new Date().getTime())) 来完成此操作。这样做时,我得到的日志告诉我调用了序列化,结果是我所期望的。

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

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

关于如何让 GraphQL 使用我的自定义标量的任何想法?

【问题讨论】:

  • 您写道,您“向名为 Date 的根添加了一个新属性”。不确定这里的“根”是什么。它是解析器地图吗?或者是别的什么?您可以在此处复制根目录的相关部分以及如何设置 graphQLOptions.schema 吗?
  • @talzaj 哦,这很好。它实际上是解析器映射,但我没有意识到 root 不是它的常用术语。我将编辑添加一些代码的问题,以便可以清楚地理解。谢谢!
  • 我昨天实际上在我的服务器上成功实现了它。因此,如果您仍然遇到问题,我可以将您的代码与适合我的代码进行比较。
  • 听起来不错。我需要我的个人笔记本电脑来获取我编写的代码,以便能够更新这篇文章。希望今晚我能找到时间来做这件事。谢谢!
  • @talzaj 我刚刚更新了帖子。如果您需要更多信息,请告诉我。谢谢!

标签: graphql apollo graphql-js


【解决方案1】:

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

【讨论】:

  • 我会尽快尝试,并在我成功后接受您的回答。谢谢回答! :)
  • 过渡到 apollo 库似乎需要做大量的工作。我找不到让这个工作的方法。现在我收到错误“预期未定义为 GraphQL 架构”,并且所有堆栈跟踪都指向 node_libraries 文件。
  • 您能否发布您的代码,包括您设置端点的位置,使用参数和分配架构的代码调用graphqlExpress
猜你喜欢
  • 2020-08-03
  • 2018-05-29
  • 2020-10-21
  • 2020-04-06
  • 2018-02-12
  • 2022-08-05
  • 2020-05-05
  • 2020-08-03
  • 2019-10-12
相关资源
最近更新 更多