GraphQL - 从嵌套的JSON对象中获取所有字段

col*_*ith 12 graphql

我正在将一个GraphQL包装器放在现有的REST API上,如Zero to GraphQL中所述,在30分钟内完成.我有一个产品的API端点,其中一个属性指向嵌套对象:

// API Response
{
  entity_id: 1,
  nested_object: {
    key1: val1,
    key2: val2,
    ...
  }
}
Run Code Online (Sandbox Code Playgroud)

是否可以定义模式,以便我可以获得整个嵌套对象而无需显式定义嵌​​套对象及其所有属性?我希望我的查询只指定我想要嵌套对象,而不需要从嵌套对象中指定我想要的所有属性:

// What I want
{
  product(id: "1") {
    entityId
    nestedObject
  }
}

// What I don't want
{
  product(id: "1") {
    entityId
    nestedObject {
      key1
      key2
      ...
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

我可以做第二个版本,但它需要许多额外的代码,包括创建NestedObjectType和指定所有嵌套属性.我还想出了如何自动获取所有键的列表,如下所示:

const ProductType = new GraphQLObjectType({
  ...

  fields: () => ({
    nestedObject: {
      type: new GraphQLList(GraphQLString),
      resolve: product => Object.keys(product.nested_object)
    }
  })
})
Run Code Online (Sandbox Code Playgroud)

不过,我还没有想出一种自动返回整个对象的方法.

小智 10

您可以尝试使用标量 JSON 类型。您可以在此处找到更多信息(基于 apollographql)

  • 添加scalar JSON到模式定义;
  • 添加{JSON: GraphQLJSON}到解析函数;
  • 在 shema 中使用 JSON 类型:

    scalar JSON
    type Query {
        getObject: JSON
    }

Run Code Online (Sandbox Code Playgroud)
  • 查询示例:

    query {
      getObject
    }

Run Code Online (Sandbox Code Playgroud)
  • 结果:

    {
      "data": {
        "getObject": {
          "key1": "value1",
          "key2": "value2",
          "key3": "value3"
        }
      }
    }

Run Code Online (Sandbox Code Playgroud)

基本代码:


    const express = require("express");
    const graphqlHTTP = require("express-graphql");
    const { buildSchema } = require("graphql");
    const GraphQLJSON = require("graphql-type-json");

    const schema = buildSchema(`
      scalar JSON

      type Query {
        getObject: JSON
      }
    `);

    const root = {
      JSON: GraphQLJSON,

      getObject: () => {
        return {
          key1: "value1",
          key2: "value2",
          key3: "value3"
        };
      }
    };

    const app = express();
    app.use(
      "/graphql",
      graphqlHTTP({
        schema: schema,
        rootValue: root,
        graphiql: true
      })
    );
    app.listen(4000);
    console.log("Running a GraphQL API server at localhost:4000/graphql");

Run Code Online (Sandbox Code Playgroud)


Eri*_*per 6

我可以做第二个版本,但它需要许多额外的代码,包括创建NestedObjectType和指定所有嵌套属性.

做吧!这将会非常棒.这是将GraphQL充分发挥其潜力的方法.

除了防止过度获取之外,它还为您提供了许多其他好处,例如类型验证,以及更易读和可维护的代码,因为您的模式可以更全面地描述您的数据.你以后会感谢你自己做额外的工作.

如果由于某种原因你真的不想走那条路并完全理解后果,你可以使用嵌套对象编码为字符串JSON.stringify.

但就像我说的,我建议你不要!