GraphQL不调用自定义标量方法

时间:2018-01-21 18:07:13

标签: graphql apollo graphql-js

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

我做了什么

  • 在我的架构中添加了scalar Date
  • 使用serialize,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'));

到目前为止我的调试

  • 我已经在方法serialize等上使用了日志,但没有一个被调用。
  • 我已从根目录中删除了Date属性,行为完全相同
  • 我已经检查过dateScalar的实例符合我的预期。我在将console.log(dateScalar.serialize(new Date().getTime()))导入不同的文件后立即调用了.toString()。当我这样做时,我得到日志告诉我序列化被调用,结果就是我所期待的。

似乎在根目录它从未将我的模式中的标量与我的自定义标量实例相关联。也许我在这里做错了什么?

我的猜测是GraphQL使用protected static boolean installedFromMarket(WeakReference<? extends Context> weakContext) { boolean result = false; Context context = weakContext.get(); if (context != null) { try { String installer = context.getPackageManager().getInstallerPackageName(context.getPackageName()); // if installer string is not null it might be installed by market if (!TextUtils.isEmpty(installer)) { result = true; // on Android Nougat and up when installing an app through the package installer (which HockeyApp uses itself), the installer will be // "com.google.android.packageinstaller" or "com.android.packageinstaller" which is also not to be considered as a market installation if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && (TextUtils.equals(installer, INSTALLER_PACKAGE_INSTALLER_NOUGAT) || TextUtils.equals(installer, INSTALLER_PACKAGE_INSTALLER_NOUGAT2))) { result = false; } // on some devices (Xiaomi) the installer identifier will be "adb", which is not to be considered as a market installation if (TextUtils.equals(installer, INSTALLER_ADB)) { result = false; } } } catch (Throwable ignored) { } } return result; } 进行序列化和解析,因为它没有找到我的序列化/解析实现。

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

1 个答案:

答案 0 :(得分:1)

TL;博士

使用SET_TARGET_PROPERTIES(Wpo PROPERTIES COMPILE_FLAGS "/GL") SET_TARGET_PROPERTIES(Wpo PROPERTIES LINK_FLAGS "/LTCG") 制作可执行架构并使用graphql-tools代替apollo-server-express

不幸的是我不熟悉express-graphql。所以我的解决方案需要用express-graphql重新替换它。幸运的是,它不需要很多改变。

这对我有用,可以进行一些修改以匹配您的代码。

首先安装包: apollo-server-express

这是代码:

npm install apollo-server-express graphql-tools

详细了解Adding a GraphQL endpoint

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