Как определить тип массива для нескольких или вложенных данных json из REST API

#rest #graphql #express-graphql

#rest #graphql #экспресс-graphql

Вопрос:

Я новичок в GraphQL. У меня возникла проблема с извлечением данных массива из API с помощью сервера express-graphql, и я нахожу где-то трудное решение. Вот сценарий.

У меня есть GET data из REST API, который имеет ответ, похожий на этот :

 {
    "id": 1,
    "name": "billy",
    "foods": [
        {
            "food":{
                "name":"crepes",
                "taste": "crunchy"
            }
        },
        {
            "food":{
                "name":"noodle",
                "taste":"spicy"
            }
        },
    ]
}
 

В моей схеме я успешно получил id и name который я реализую следующим образом :

 const FoodsType= new GraphQLObjectType({
  name: 'foods',
  fields: () => ({
    id:{ type: GraphQLInt },
    name:{ type: GraphQLString},
    foods: { type: GraphQLArray}
  })
});
 

Как вы можете видеть в моем коде выше, мне не удалось получить данные foods, которые содержат данные массива, потому что нет скалярного типа, подобного GraphQLArray .
Мой вопрос в том, как мы получаем foods данные, содержащие food внутри них несколько данных json?

Комментарии:

1. foods: { type: new GraphQLList(FoodsType) }, ? graphql.org/graphql-js/type

2. Тогда как мы должны предоставлять несколько food объектов внутри foods ? Как мы должны определить FoodsType , когда food также тип объекта

3. FoodsType я пытаюсь это food: {type: new GraphQLObjectType(FoodDetailType)} сделать, но он выдает ошибку

4. почему существует объект внутри объекта (внутри массива), требуется ли это? … определите его способом graphql и преобразуйте данные в распознавателе, а не просто пересылаете?

5. что такое «прямой», когда вы используете express ??? … прямой может быть с помощью ‘REST Link’… затем вам нужен тип для каждого уровня глубины ответа… или определите его по-своему, преобразуя ответ REST в соответствии с вашими потребностями перед возвратом

Ответ №1:

 const ResType= new GraphQLObjectType({
   name: 'response',
   field:() => ({
       name: {type: GraphQLString}, 
       taste: {type: GraphQLString}
   })
   
});


const FoodsType= new GraphQLObjectType({
  name: 'foods',
  fields: () => ({
    id:{ type: GraphQLInt },
    name:{ type: GraphQLString},
    foods: { type: new GraphQLList(ResType)}
  })
});
 

Комментарии:

1. в настоящее время у меня есть этот тип const FoodsType = new GraphQLObjectType({ name: 'foods', fields: () => ({ name: { type: GraphQLString }, taste: { type: GraphQLString } }) }); питания, но похоже, что добавление foods: {type: FoodsType[]} приводит к синтаксической ошибке.

2. О, я вижу, я изменил ответ после проверки приведенного здесь примера. Синтаксическая ошибка может заключаться в том, что сам механизм синтаксического анализа не распознает [] . graphql.org/graphql-js/type/#graphqlobjecttype

3. Спасибо за модификацию моего кода. Но все же похоже foods: { type: Array<ResType>} , что в моем случае это также приводит к синтаксической ошибке.

4. Ошибка синтаксиса: неожиданный токен ‘}’

5. номер строки ошибки указывает на то, где foods: { type: Array<ResType>} находится?

Ответ №2:

После некоторой попытки мне, наконец, удается решить эту проблему, определив типы каждого уровня глубины. Вот мой ответ для файла схемы.

   const FoodsType = new GraphQLObjectType({ 
    name: 'foods',
    fields: () => ({
      id:{ type: GraphQLInt },
      name: { type: GraphQLString },
      foods:{ type: new GraphQLList(FoodType) }
    })
  });
  
  const FoodType = new GraphQLObjectType({
    name: 'food',
    fields: () => ({
      food: {type: FoodDetail}
    })
  });
  
  const FoodDetail = new GraphQLObjectType({
    name: 'fooddetail',
    fields: () => ({
      name:{ type: GraphQLString },
      taste:{ type: GraphQLString}
    })
  });
 

И вот решатель, который я получаю из API

   const RootQuery = new GraphQLObjectType({
    name: 'RootQueryType',
    fields: {
      foods: {
        type: FoodsType,
        args: {
          id: { type: GraphQLInt }
        },
        resolve(parent, args) {
          return axios
            .get(`https://hereisanapi/${args.id}`)
            .then(res => {
              return res.data;
            });
        }
      }
    }
  });
 

Затем в запросе GraphQL я вставляю это.

 {
  foods(id:1){
    food{
      name,
      taste
    }
  }
} 
 

Комментарии:

1. … и вы можете легко удалить средний тип… return { id: res.data.id, name: res.data.name, foods: [...res.data.foods.map(item=>item.food)] } (чтобы увидеть массив / структуру) … или даже напрямую foods: res.data.foods.map(item=>item.food)

2. определенно более простой подход!. Спасибо @xadm 🥂