模式拼接graphql微服务约定之间的通信

时间:2019-05-14 01:50:56

标签: node.js graphql apollo

我有以下结构,我认为这很普遍。我一直在寻找并且找不到关于模式缝合服务相互调用的推荐方法的任何信息(尽管前端仍在使用)。这是我的情况:

Api Gateway模式针脚:

  • 用户服务
  • 邮政服务

posts服务使用mongodb,而users服务使用PostgreSQL。帖子服务的架构仅包含user_id,而不包括完整用户。当我需要帖子页面(带有相应的用户信息)时,我正在使用post-service中的getPosts解析器中的node-fetch调用用户服务,如下所示:

{
  getUsers(user_id__in:[1,5,9,3]){
    username
    join_date
  }
}

与其余的apollo-graphql相比,这种解决方案感觉有点“肮脏”。

是否更常见的是忽略graphql部分来解析数据并使用apollo-graphql的基础快递服务器提供的典型的其他终结点结构?如果不是,我应该直接调用其他服务还是通过api网关调用它们?如果我应该通过api网关调用它们,那么有什么方法可以使用一些Apollo功能(因为服务是按模式缝合的)以一种优雅的方式来调用api网关。

1 个答案:

答案 0 :(得分:1)

您的问题没有显示API网关的任何现有代码,但我假设您正在拼接模式as described in the docs。每个服务的架构应仅提供适合其特定域的字段。例如,posts服务架构不应包含对用户的任何引用。将模式拼接在一起时,您可以通过提供链接不同服务的附加字段来扩展现有类型。

const extensions = `
extend type User {
  posts
}

extend type Post {
  user
}
`

const mergedSchema = mergeSchemas({
  schemas: [
    usersSchema,
    postsSchema,
    extensions,
  ],
  resolvers: {
    User: {
      posts: {
        fragment: `... on User { id }`,
        resolve(user, args, context, info) {
          return info.mergeInfo.delegateToSchema({
            schema: postsSchema,
            operation: 'query',
            fieldName: 'posts',
            args: {
              userId: user.id,
            },
            context,
            info,
          });
        },
      },
    },
    Post: {
      user: {
        fragment: `... on Post { userId }`,
        resolve(post, args, context, info) {
          return info.mergeInfo.delegateToSchema({
            schema: postsSchema,
            operation: 'query',
            fieldName: 'user',
            args: {
              id: post.userId,
            },
            context,
            info,
          });
        },
      },
    },
  },
});

在这里,我们将从用户服务中扩展User类型,以包括一个posts字段。我们使用delegateToSchema来表示该额外字段实际上应由邮政服务的架构来解决,方法是查询posts并将用户ID作为userId参数(实际字段和参数名称)传递将需要匹配您的架构)。我们类似地向每个user添加一个Post字段,并将该字段委托给用户服务模式。

请检查docs了解更多详细信息。