首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >GraphQL黑盒/“任何”类型?

GraphQL黑盒/“任何”类型?
EN

Stack Overflow用户
提问于 2017-08-10 03:06:57
回答 6查看 21.1K关注 0票数 40

是否可以将GraphQL中的字段指定为黑盒,就像Flow具有"any“类型一样?我的模式中有一个字段,它应该能够接受任意值,可以是字符串、布尔值、对象、数组等。

EN

回答 6

Stack Overflow用户

发布于 2017-08-10 06:58:50

我想出了一个折中的解决方案。而不是试图将这种复杂性推到GraphQL上,我选择只使用String类型,并在将数据设置到字段之前对其进行JSON.stringify。因此,所有内容都被字符串化了,稍后在我的应用程序中,当我需要使用这个字段时,我会对结果执行JSON.parse操作,以返回所需的对象/数组/布尔值/等等。

票数 39
EN

Stack Overflow用户

发布于 2017-12-19 14:05:56

@mpen的答案很好,但我选择了一个更紧凑的解决方案:

代码语言:javascript
复制
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
    }
  }
})

然后我的解析器看起来像这样:

代码语言:javascript
复制
{
  Object: ObjectScalarType,
  RootQuery: ...
  RootMutation: ...
}

我的.gql看起来像这样:

代码语言:javascript
复制
scalar Object

type Foo {
  id: ID!
  values: Object!
}
票数 22
EN

Stack Overflow用户

发布于 2017-08-10 03:14:18

是。只需创建一个允许任何内容的新GraphQLScalarType即可。

这是我写的一个允许对象。您可以对其进行一点扩展,以允许更多的根类型。

代码语言:javascript
复制
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;
    }
}
票数 13
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45598812

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档