代码之家  ›  专栏  ›  技术社区  ›  Rudy

构建GraphQL解析器以返回字符串列表-接收[object]而不是字符串

  •  0
  • Rudy  · 技术社区  · 7 年前

    我正在开发一个查询 OrientDB 使用GraphQL的图形数据库。它使用 Apollo Server

    我想构建一个查询,它只返回每个“Topic”对象的“name”字段作为字符串列表。例如。:

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

    以及相关的 分解器 :

    //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;
    

    但是,当我尝试实现上述类型定义和解析器时,我会收到一个字符串列表,这些字符串都是“[object]”,而不是实际的字符串:

    {
      "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 回复  |  直到 7 年前
        1
  •  1
  •   Daniel Rearden    7 年前

    您最初的方法没有按预期工作,因为您返回了一个对象数组。您的第二次尝试返回null,因为您没有在解析器中返回任何内容。解析程序应始终返回将解析为该值的值或承诺,否则字段的解析值将始终为null。

    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)
    }