node.js - 模式缝合的graphql微服务约定之间的通信
问题描述
我有以下我认为相当普遍的结构。我一直在寻找并找不到任何关于模式拼接服务相互调用的推荐方式的任何信息(同时仍被前端使用)。这是我的情况:
Api Gateway 模式缝合:
- 用户服务
- 邮政服务
帖子服务使用 mongodb,用户服务使用 PostgreSQL。帖子服务的架构仅包含 user_id 而不是完整用户。当我需要一页帖子(带有相应的用户信息)时,我正在使用帖子服务中的 getPosts 解析器中的 node-fetch 调用用户服务,如下所示:
{
getUsers(user_id__in:[1,5,9,3]){
username
join_date
}
}
与 apollo-graphql 的其余部分的优雅相比,这个解决方案感觉有点“肮脏”。
是否更常见的是忽略用于解析数据的 graphql 部分并使用 apollo-graphql 的底层快速服务器提供的典型休息端点结构?如果不是,我应该直接调用其他服务还是通过 api 网关调用它们?如果我应该通过 api 网关调用它们,是否有任何内置的优雅方式可以使用某些 Apollo 功能调用 api 网关(因为服务是模式缝合的)。
解决方案
您的问题没有显示您现有的任何 API 网关代码,但我假设您正在按照 docs 中的描述拼接您的模式。每个服务的模式应该只提供适合其特定领域的字段。例如,帖子服务模式不应包含对用户的任何引用。当您将模式拼接在一起时,您可以通过提供链接不同服务的附加字段来扩展现有类型。
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
并将解析该字段委托给用户服务模式。
请查看文档以获取更多详细信息。
推荐阅读
- html - HTML 似乎没有注册我尝试连接外部 CSS
- javascript - 用指定的字符串替换字符串
- node.js - 将 vue.js 客户端、node.js 服务器应用程序和一个二进制服务组合为单个图像
- c++ - 为什么 C++20 范围适配器的返回视图不是常量表达式?
- jsx - editorconfig - 花括号内的空格
- sql - 隔夜规则查询
- shell - 使用 unix shell 将文件从 windows(remote) 文件夹移动到子文件夹
- python - Python将数据添加到数组中
- flutter - 如何使用远程桌面连接在域 URL 上部署 Flutter Web 应用程序?
- ruby-on-rails - yaml:解组错误:无法将 !!str `https:/...` 解组为 [] 字符串