GraphQL - получить все поля из вложенного объекта JSON

Я помещаю оболочку GraphQL поверх выходящего REST API, как описано в Zero to GraphQL за 30 минут. У меня есть конечная точка 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)
    }
  })
})

Я не понял способ автоматического возврата всего объекта.

Ответ 1

Я могу сделать вторую версию, но она требует большого количества дополнительного кода, включая создание NestedObjectType и указание всех вложенных свойств.

Сделай это! Это будет замечательно. Это путь, чтобы использовать GraphQL в полном объеме.

Помимо предотвращения чрезмерной выборки, он также дает вам много других преимуществ, таких как проверка типов, и более читаемый и поддерживаемый код, поскольку ваша схема дает более полное описание ваших данных. Позднее вы поблагодарите себя за выполнение дополнительной работы.

Если по какой-то причине вы действительно не хотите идти по этому маршруту, хотя и полностью понимаете последствия, вы можете кодировать вложенные объекты в виде строк с помощью JSON.stringify.

Но, как я уже сказал, я не рекомендую этого делать!

Ответ 2

Вы можете попробовать использовать скалярный тип JSON. Вы можете найти больше здесь (на основе 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");