【问题标题】:Apollo/GraphQL: Setting Up Resolver for String Fields?Apollo/GraphQL:为字符串字段设置解析器?
【发布时间】:2017-01-11 14:26:26
【问题描述】:

http://localhost:8080/graphiql 的 GraphiQL 中,我正在使用这个查询:

{
  instant_message(fromID: "1"){
    fromID
    toID
    msgText
  }
}

我收到了这样的回复:

{
  "data": {
    "instant_message": {
      "fromID": null,
      "toID": null,
      "msgText": null
    }
  },
  "errors": [
    {
      "message": "Resolve function for \"instant_message.fromID\" returned undefined",
      "locations": [
        {
          "line": 3,
          "column": 5
        }
      ]
    },
    {
      "message": "Resolve function for \"instant_message.toID\" returned undefined",
      "locations": [
        {
          "line": 4,
          "column": 5
        }
      ]
    },
    {
      "message": "Resolve function for \"instant_message.msgText\" returned undefined",
      "locations": [
        {
          "line": 5,
          "column": 5
        }
      ]
    }
  ]
}

我尝试根据此处找到的示例设置我的系统:

https://medium.com/apollo-stack/tutorial-building-a-graphql-server-cddaa023c035#.s7vjgjkb7

看那篇文章,似乎没有必要为字符串字段设置单独的解析器,但我一定遗漏了一些东西。

更新解析器以从字符串字段返回结果的正确方法是什么?示例代码将不胜感激!

非常感谢大家的任何想法或信息。

连接器

import Sequelize from 'sequelize';

//SQL CONNECTORS
const db = new Sequelize(Meteor.settings.postgres.current_dev_system.dbname, Meteor.settings.postgres.current_dev_system.dbuser, Meteor.settings.postgres.current_dev_system.dbpsd, {
  host: 'localhost',
  dialect: 'postgres',

});

db
    .authenticate()
    .then(function(err) {
        console.log('Connection to Sequelize has been established successfully.');
    })
    .catch(function (err) {
        console.log('Unable to connect to the Sequelize database:', err);
    });

const IMModel = db.define('IM', {
    id: {type: Sequelize.INTEGER, primaryKey: true, autoIncrement: true},
    fromID: {type: Sequelize.STRING},
    toID: {type: Sequelize.STRING},
    msgText: {type: Sequelize.STRING}
});

IMModel.sync({force: true}).then(function () {
    // Table created
    return IMModel.create({
        fromID: '1',
        toID: '2',
        msgText: 'msg set up via IMModel.create'
    });
});

const IM = db.models.IM;
export {db, IM };

架构

const typeDefinitions = [`

type instant_message {
  id: Int
  fromID: String
  toID: String
  msgText: String
}
type Query {
  instant_message(fromID: String, toID: String, msgText: String): instant_message
}
type RootMutation {
  createInstant_message(
    fromID: String!
    toID: String!
    msgText: String!
  ): instant_message
}
schema {
  query: Query,
  mutation: RootMutation
}
`];

export default typeDefinitions;

解决者

import * as connectors from './db-connectors';
import { Kind } from 'graphql/language';
const b = 100;

const resolvers = {
    Query: {
        instant_message(_, args) {
            const a = 100;
            return connectors.IM.find({ where: args });
        }
    },
    RootMutation: {
        createInstant_message: (__, args) => { return connectors.IM.create(args); },
  },

};

export default resolvers;

【问题讨论】:

    标签: meteor graphql apollo-server


    【解决方案1】:

    当您定义 GraphQLObjectTypes 时,您需要为其每个字段提供解析器。

    您使用多个字段定义了 instant_message,但没有为每个字段提供解析器。 此外,您使用常规打字稿字段定义了这些字段的类型,而您需要使用 GraphQL 类型(GraphQLInt, GraphQLString, GrapQLFloat 等)定义它。

    所以定义你的类型应该是这样的:

    let instant_message = new GraphQLObjectType({
      id: { 
        type: GraphQLInt,
        resolve: (instantMsg)=> {return instantMsg.id}
      }
      fromID: { 
        type: GraphQLString,
        resolve: (instantMsg)=> {return instantMsg.fromID}
      }
      toID: {
        type: GraphQLString,
        resolve: (instantMsg)=> {return instantMsg.toID}
      }
      msgText: { 
        type: GraphQLString,
        resolve: (instantMsg)=> {return instantMsg.msgText}
      }
    })
    

    此外,您需要按如下方式定义查询:

    let Query = new GraphQLObjectType({
        name: "query",
        description: "...",
    
        fields: () => ({
            instant_messages: {
                type: new GraphQLList(instant_message),
                args: {
                    id: {type: GraphQLInt}
                },
                resolve: (root, args) => {
                    connectors.IM.find({ where: args })
                }
            }
        })
    })
    

    【讨论】:

    • Apollo 与 GraphQL 有点不同。这是 Apollo 的语法吗?
    • 我尝试了语法。它没有抛出错误,但我仍然得到相同的结果。
    • 我明白了。它可能真的与您的查询不返回数组有关。尝试像其他人建议的那样更改为[instant_message] 而不是instant_message
    • 所以,应该是return connectors.IM.find({ where: args });,而不是return [connectors.IM.find({ where: args })];?
    • 用查询类型中的instant_message 列表更新了我的答案,告诉我你的想法
    【解决方案2】:

    问题是查询不需要数组, 请修复它: type Query { instant_message(fromID: String, toID: String, msgText: String): [instant_message] }

    那么你应该确保解析器返回对象数组,如果它不起作用,那么解析器没有返回一个数组。

    【讨论】:

    • 我已将架构更新为type Query { instant_message(fromID: String, toID: String, msgText: String): [instant_message] },解析器为return connectors.IM.find({ where: args });。 GraphiQL 正在响应,"message": "Expected Iterable, but did not find one for field Query.instant_message." 我是否需要更新解析器和架构?
    猜你喜欢
    • 1970-01-01
    • 2018-02-18
    • 2018-10-04
    • 2020-10-07
    • 2019-05-18
    • 2021-07-26
    • 2020-08-26
    • 2020-05-10
    • 2018-03-19
    相关资源
    最近更新 更多