Построение GraphQL Resolver для возврата списка строк - получение [объектный объект] вместо строк - PullRequest
0 голосов
/ 27 октября 2018

Я разрабатываю веб-приложение, которое запрашивает базу данных Graph OrientDB , используя GraphQL. Он использует Apollo Server для разрешения входящих запросов GraphQL.

Я хочу создать запрос, который будет просто возвращать поле «имя» для каждого объекта «Тема» в виде списка строк. e.g.:

{
  "data": {
    "allTopicNames": [
      "Topic 1",
      "Topic 2",
      "Topic 3",
      "Topic 4"
    ]
  }
}

Для этого я создал Определение типа :

// Imports: GraphQL
import { gql } from 'apollo-server-express';

// GraphQL: TypeDefs
const TYPEDEFS = gql`
type Query {
    allTopics: [Topic]
    topic(name: String): [Topic]
    allTopicNames: [String] //This is the new Type Definition -- we want a list of Strings
  }
type Topic {
    name: String
}
`;

// Exports
export default TYPEDEFS;

И связанный Resolver :

//Connect to OrientDB
var OrientJs = require('orientjs');

var server = OrientJs({
    host: "localhost",
    port: "2424",
    username: "root",
    password: "root"
});

var db = server.use({
    name: 'database',
    username: 'root',
    password: 'root'
});

// GraphQL: Resolvers
const RESOLVERS = {
    Query: {
        allTopics: () => {
            return db.query('SELECT FROM Topic ORDER BY name');
        },
        allTopicNames: () => {
            return db.query('SELECT name FROM Topic ORDER BY name'); //This is the new resolver
        },
        topic: (obj, args) => {
            return db.query('SELECT FROM Topic WHERE name=\'' + args.name + '\' LIMIT 1');
        }
    }
};

// Exports
export default RESOLVERS;

Однако, когда я пытаюсь реализовать описанные выше Определение типов и Resolver, я получаю список строк, которые все являются «[объектными объектами]» вместо реальных строк:

{
  "data": {
    "allTopicNames": [
      "[object Object]",
      "[object Object]",
      "[object Object]",
      "[object Object]"
    ]
  }
}

Я попытался добавить в распознаватель некоторый код, который будет перебирать каждый объект и создавать правильный список строк для возврата:

// GraphQL: Resolvers
const RESOLVERS = {
    Query: {
        allTopics: () => {
            return db.query('SELECT FROM Topic ORDER BY name');
        },
        allTopicNames: () => {
            let the_list_of_records = db.query('SELECT name FROM Topic ORDER BY name').then(res => { 
                let the_list_of_names = []; //We'll return a List of Strings using this
                for(var i = 0; i < res.length; i++){
                    the_list_of_names.push(res[i]['name']);
                }
                console.log(the_list_of_names);
                return the_list_of_names;
            });
        },
        topic: (obj, args) => {
            return db.query('SELECT FROM Topic WHERE name=\'' + args.name + '\' LIMIT 1');
        }
    }
};

Но это не сработало, и вместо этого было возвращено нулевое значение:

{
  "data": {
    "allTopicNames": null
  }
}

Я искренне не понимаю, почему я не могу получить простой список строк для заполнения через этот преобразователь. Возможно, я упускаю что-то очевидное - любое понимание очень ценится!

1 Ответ

0 голосов
/ 27 октября 2018

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

Значение the_list_of_records будет Обещанием, поэтому вы можете простовернуть то и этого должно быть достаточно.Но мы можем сделать этот код немного проще для чтения, используя map, например:

allTopicNames: () => {
  return db.query('SELECT name FROM Topic ORDER BY name').then(res => {
    return res.map(topic => topic.name)
  })
}

// using async/await
allTopicNames: async () => {
  await topics = await db.query('SELECT name FROM Topic ORDER BY name')
  return topics.map(topic => topic.name)
}
...