是否可以将GraphQL中的字段指定为黑盒,就像Flow具有"any“类型一样?我的模式中有一个字段,它应该能够接受任意值,可以是字符串、布尔值、对象、数组等。
发布于 2017-08-10 06:58:50
我想出了一个折中的解决方案。而不是试图将这种复杂性推到GraphQL上,我选择只使用String类型,并在将数据设置到字段之前对其进行JSON.stringify。因此,所有内容都被字符串化了,稍后在我的应用程序中,当我需要使用这个字段时,我会对结果执行JSON.parse操作,以返回所需的对象/数组/布尔值/等等。
发布于 2017-12-19 14:05:56
@mpen的答案很好,但我选择了一个更紧凑的解决方案:
const { GraphQLScalarType } = require('graphql')
const { Kind } = require('graphql/language')
const ObjectScalarType = new GraphQLScalarType({
name: 'Object',
description: 'Arbitrary object',
parseValue: (value) => {
return typeof value === 'object' ? value
: typeof value === 'string' ? JSON.parse(value)
: null
},
serialize: (value) => {
return typeof value === 'object' ? value
: typeof value === 'string' ? JSON.parse(value)
: null
},
parseLiteral: (ast) => {
switch (ast.kind) {
case Kind.STRING: return JSON.parse(ast.value)
case Kind.OBJECT: throw new Error(`Not sure what to do with OBJECT for ObjectScalarType`)
default: return null
}
}
})然后我的解析器看起来像这样:
{
Object: ObjectScalarType,
RootQuery: ...
RootMutation: ...
}我的.gql看起来像这样:
scalar Object
type Foo {
id: ID!
values: Object!
}发布于 2017-08-10 03:14:18
是。只需创建一个允许任何内容的新GraphQLScalarType即可。
这是我写的一个允许对象。您可以对其进行一点扩展,以允许更多的根类型。
import {GraphQLScalarType} from 'graphql';
import {Kind} from 'graphql/language';
import {log} from '../debug';
import Json5 from 'json5';
export default new GraphQLScalarType({
name: "Object",
description: "Represents an arbitrary object.",
parseValue: toObject,
serialize: toObject,
parseLiteral(ast) {
switch(ast.kind) {
case Kind.STRING:
return ast.value.charAt(0) === '{' ? Json5.parse(ast.value) : null;
case Kind.OBJECT:
return parseObject(ast);
}
return null;
}
});
function toObject(value) {
if(typeof value === 'object') {
return value;
}
if(typeof value === 'string' && value.charAt(0) === '{') {
return Json5.parse(value);
}
return null;
}
function parseObject(ast) {
const value = Object.create(null);
ast.fields.forEach((field) => {
value[field.name.value] = parseAst(field.value);
});
return value;
}
function parseAst(ast) {
switch (ast.kind) {
case Kind.STRING:
case Kind.BOOLEAN:
return ast.value;
case Kind.INT:
case Kind.FLOAT:
return parseFloat(ast.value);
case Kind.OBJECT:
return parseObject(ast);
case Kind.LIST:
return ast.values.map(parseAst);
default:
return null;
}
}https://stackoverflow.com/questions/45598812
复制相似问题