Apollo / GraphQL: настройка преобразователя для строковых полей?

В GraphiQL на http://localhost:8080/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;

person VikR    schedule 03.09.2016    source источник


Ответы (2)


Когда вы определяете свои GraphQLObjectType, вам необходимо предоставить преобразователь для каждого из их полей.

Вы определили свой 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 })
            }
        }
    })
})
person Kesem David    schedule 03.09.2016
comment
Apollo немного отличается от GraphQL. Это синтаксис Аполлона? - person VikR; 04.09.2016
comment
Я попробовал синтаксис. Ошибка не возникла, но я все равно получаю те же результаты. - person VikR; 04.09.2016
comment
Понятно. это действительно может быть связано с тем, что ваш запрос не возвращает массив. попробуйте изменить на [instant_message] вместо instant_message, как предложил другой парень - person Kesem David; 04.09.2016
comment
Значит, вместо return connectors.IM.find({ where: args }); должно быть return [connectors.IM.find({ where: args })];? - person VikR; 04.09.2016
comment
Обновил мой ответ списком instant_message в типе запроса, скажите, что вы думаете - person Kesem David; 04.09.2016
comment
Я только что попробовал, но аномалия все еще присутствует. Не могли бы вы опубликовать небольшой пример кода? - person VikR; 04.09.2016
comment
Вы пробовали это без [], окружающего find? - person Kesem David; 04.09.2016
comment
Просто чтобы прояснить комментарий VikR: все библиотеки Apollo используют стандартный GraphQL, для него нет другого синтаксиса. - person helfer; 02.11.2016

Проблема в том, что запрос не ожидает массива. Исправьте это: type Query { instant_message(fromID: String, toID: String, msgText: String): [instant_message] }

Затем вы должны убедиться, что преобразователь возвращает массив объектов. Если он не работает, преобразователь не возвращает массив.

person HagaiCo    schedule 04.09.2016
comment
Я обновил схему до 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." Нужно ли мне обновлять резолвер, а также схему? - person VikR; 05.09.2016