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