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

GraphQL - Get all fields from nested JSON object

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

// API Response
{
  entity_id: 1,
  nested_object: {
    key1: val1,
    key2: val2,
    ...
  }
}

是否可以定义架构,以便在不显式定义嵌​​套对象及其所有属性的情况下获取整个嵌套对象?我希望我的查询只指定我想要嵌套对象,而不需要指定我想要的嵌套对象的所有属性:

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

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

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

const ProductType = new GraphQLObjectType({
  ...

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

不过,我还没有找到自动 return 整个对象的方法。

I can do the second version, but it requires lots of extra code, including creating a NestedObjectType and specifying all the nested properties.

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

除了防止过度获取外,它还为您提供了很多其他好处,例如类型验证,以及更具可读性和可维护性的代码,因为您的模式提供了更完整的数据描述。稍后您会感谢自己提前做了额外的工作。

如果出于某种原因您真的不想走那条路并完全理解后果,您可以使用 JSON.stringify.

将嵌套对象编码为字符串

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

您可以尝试使用标量 JSON 类型。您可以找到更多 here (based on apollographql).

  • scalar JSON 添加到架构定义;
  • {JSON: GraphQLJSON}添加到解析函数中;
  • 使用 JSON 输入 shema:

    scalar JSON
    type Query {
        getObject: JSON
    }

  • 查询示例:

    query {
      getObject
    }

  • 一个结果:

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

基本代码:


    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");