【问题标题】:Dynamic (Unique) Objects in GraphQlGraphQl 中的动态(唯一)对象
【发布时间】:2016-02-22 12:37:44
【问题描述】:

我在看 graphql。是否可以定义具有任意属性的对象?假设我有一些数据,例如:

editOptions : { boxes : 3 , size : { width: 23,height:32} , color: #434343 }, etc...}

这是在:

{ ... , box : { editOptions : {...} }, ... }

假设 editOptions 从来没有相同的结构,有时没有颜色是有用的,只是为了举例。在猫鼬中,可以将类型定义为:

编辑选项:{}

这些 editOptions 通常对于每个框都是唯一的。有些属性是共享的,但大多数是独一无二的。

所以我的问题是,有没有办法做到这一点?或者这是不好的做法,我应该改变我的模型。

谢谢。

【问题讨论】:

    标签: javascript graphql graphql-js


    【解决方案1】:

    你有两个选择。

    1。接口

    如果editOptions 可能因类型而异,但对于该特定类型是一致的,您可以使用Interface (node.js example)。

    假设您有两个对象,一个盒子和一个球体。您可以定义一个同时实现的对象接口:

    interface Object
    type Box implements Object {
      editOptions: BoxOptions
    }
    type BoxOptions {
      boxes: Int,
      size: ...,
      color: ...
    }
    type Sphere implements Object {
      editOptions: SphereOptions
    }
    type SphereOptions {
      spheres: Int,
      ...
    }
    type Query {
      objects: [Object]
    }
    

    然后,在您的查询中,您将返回一个 Object,以及基于每种类型的请求选项:

    query Query {
      objects(filter: "...") {
        ... on Box {
          editOptions {
            boxes
            size
          }
        }
        ... on Sphere {
          editOptions {
            spheres
          }
        }
      }
    }
    

    在返回的 JSON 中,框将在 editOptions 下具有 boxessize 字段,球体将具有 spheres

    有时没有颜色是有用的

    如果某些框没有颜色,则该字段将为空(但仍存在于架构中)。

    2。 JSON

    如果editOptions 真的是可变的,您可以将字段定义为字符串,然后通过序列化的 JSON 发送。您将丢失所有类型验证,但每个对象的结构可以是完全任意的。只需确保您的客户了解如何处理它。

    【讨论】:

    • 嘿,很抱歉回复晚了,这确实是一个很好的解决方案,谢谢。问题是不会有盒子、球体、立方体等。我们必须让它向无限的可能性开放 =) 但这绝对是一种可能性。谢谢!
    【解决方案2】:

    使用GraphQLScalarType,简单实现如下:

    import { GraphQLScalarType } from 'graphql/type';
    import { GraphQLError } from 'graphql/error';
    import { Kind } from 'graphql/language';
    
    const ObjectType = new GraphQLScalarType({
      name: 'ObjectType',
      serialize: value => value,
      parseValue: value => value,
      parseLiteral: (ast) => {
        if (ast.kind !== Kind.OBJECT) {
          throw new GraphQLError(
            `Query error: Can only parse object but got a: ${ast.kind}`, 
            [ast],
          );
        }
        return ast.value;
      },
    });
    
    const ReturnType = new GraphQLObjectType({
      name: 'ReturnType',
      fields: {
        // ...
        editOptions: { type: ObjectType },
        // ...
      },
    });
    

    【讨论】:

    • 我正在尝试使用它,但我收到了这条消息:"message": "Argument \"data\" has invalid value {a: \"A\", b: \"B\"}.\nExpected type \"ObjectType\", found {a: \"A\", b: \"B\"}."。任何想法问题出在哪里?
    • 看来您现在可以在npmjs.com/package/graphql-type-json 找到它作为公共模块。
    【解决方案3】:

    尝试 GraphQL.js 的 JSON 标量类型:graphql-type-json。它对我很有用。

    在将 SDL 与 GraphQL 工具一起使用时,将 GraphQLJSON 定义为架构中适当标量类型的解析器:

    import { makeExecutableSchema } from 'graphql-tools';
    import GraphQLJSON from 'graphql-type-json';
    
    const typeDefs = `
      scalar JSON
    
      type MyType {
        editOptions: JSON
      }
    `;
    
    const resolvers = {
      JSON: GraphQLJSON,
    };
    
    export default makeExecutableSchema({ typeDefs, resolvers });
    

    您也可以在以编程方式构建的架构中使用它。

    查看more details on this package

    【讨论】:

      猜你喜欢
      • 2018-04-07
      • 1970-01-01
      • 1970-01-01
      • 2018-02-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-23
      • 1970-01-01
      • 2020-09-16
      相关资源
      最近更新 更多