Apollo GraphQL - Связанные типы не включены в ответ на подписку

Допустим, у меня есть модель сообщений и комментариев. Сообщение имеет много комментариев. В React Apollo я использую subscribeToMore в запросе для определенного сообщения.

Запрос выглядит следующим образом:

query getPost(id: ID!){
    id, title, comments { id }
}

И подписка, которая возвращает сообщение с любыми новыми комментариями:

subscription commentAdded(postId: ID!){
    id, title, comments { id }
}

Запрос работает. Он возвращает все связанные комментарии, которые я затем могу отобразить в виде списка на странице.

Тем не менее, при использовании помощника subscribeToMore для запроса я получаю ошибку отслеживания всякий раз, когда отправляется подписка на событие.

Cannot read property 'Comment' of undefined.

Странно то, что если я удалю комментарий, подписка будет выглядеть как ...

subscription commentAdded(postId: ID!){
    id, title
}

... работает отлично. Я не понимаю, почему он, кажется, рассматривает комментарии как связанные с неопределенной моделью.

Это не просто проблема с комментариями -> сообщениями, это происходит с любой моделью, которая пытается вернуть подписку с ассоциацией.

отправить запрос:

    post: async (parent, {id}, {models}) => {
        return await models.Post.findByPk(id);
    }

saveComment преобразователь:

    saveComment: async (parent, {postId, comment}, {models, me}) => {
        let post = await models.Post.findByPk(postId);
        let comment = await models.Comment.create({comment, postId});
        await pubsub.publish("COMMENT_CREATED", {
            commentCreated: post,
            postId
        })
    }

комментарийСозданная подписка:

    commentCreated: {
        subscribe: withFilter(
            () => pubsub.asyncIterator(["COMMENT_CREATED"]),
            (payload, variables) => {
                return payload.postId == variables.postId
            }
        )
    }

Преобразователь типов сообщений

Post: {
    comments: async (post, args, {models}) => {
        return await models.Comment.findAll({where:{postId: post.id}});
    }
}

Инициализация сервера:

const server = new ApolloServer({
    typeDefs: schema,
    resolvers,
    subscriptions: {
        onConnect: (connectionParams, webSocket) => {
            return true
        },
    },
    context: async ({ req, connection }) => {
        if(connection){
            return connection.context;
        }else{
            const me = await getMe(req);
            return {
                models,
                me,
                secret: process.env.SECRET,
            };
        }
    }
});

person NathanL    schedule 08.09.2019    source источник
comment
Измените свой вопрос, включив в него соответствующие преобразователи.   -  person Daniel Rearden    schedule 09.09.2019
comment
Отредактировано. Это странно, потому что подписка работает, поскольку содержит исходную модель, но ассоциации не работают. И я знаю, что ассоциации набраны правильно, поскольку они работают в запросе. Похоже, что это что-то, относящееся конкретно к настройкам подписки, но я не уверен.   -  person NathanL    schedule 09.09.2019
comment
Я могу настроить его так, чтобы он мог запускать новый запрос каждый раз, когда добавляются данные ответа, что работает, но это раздражающая работа для чего-то, что должно быть довольно простым.   -  person NathanL    schedule 09.09.2019
comment
Это похоже на проблему с вашей context функцией. Контекст с подписками немного шаткий. Можете ли вы включить и это?   -  person Daniel Rearden    schedule 09.09.2019


Ответы (1)


Ваша функция context возвращает только connection.context, который не будет включать какие-либо настраиваемые свойства, которые вы хотите включить (me, models и т. Д.). Если вы сделаете что-то подобное, это должно решить проблему:

context: async ({ req, connection }) => {
  const context = {
    models,
    secret: process.env.SECRET,
  };

  if(connection){
    return { ...connection.context, ...context };
  } else {
    const me = await getMe(req);
    return { ...context, me };
  }
}
person Daniel Rearden    schedule 09.09.2019