上一篇我们建立了 gateway ,也把 Task Service 安装了 federation 的 dependency
接着我们建立 User Service 和 Message Service,也都需要安装 federation
之後在 User Service 写一个 Create User 的 API
root
├── services
│ ├── task (port: 4002)
│ ├── user (port: 4001)
│ └── message (port: 4003)
└── gateway (port: 4000)
根据之前的情境
一个 Task 会由一个 User 所建立
一个 User 可以有多的 Task
Task 必须与 User 有所关联,所以我们在 Task 中会新增一个 UserId 的栏位
使用 @key(fields: "_id")
directive 设定 User 要接收什麽栏位,这边以 _id 为例子
在 model 中使用 @Directive 设定
@Directive(`@key(fields: "_id")`)
export class User extends Document {
@Field(() => ID)
_id: string;
}
type User @key(fields: "_id") {
_id: ID!
name: String!
}
在 resolver 中还有另一个方法 resolveReference
,当有相关的资源要使用 User 的实体时,Apollo Gateway 便能使用它
注意的是要在 resolveReference
加上 @ResolveReference
decorator
@ResolveReference()
resolveReference(reference: { __typename: string; _id: string }) {
return this.usersService.findById(reference._id);
}
使用 extend
来标记 User
在 Task 中新增一个 user 的 model ,指定要 extend
的栏位
@Directive('@extends')
@Directive(`@key(fields: "_id")`)
@ObjectType()
export class User {
@Directive('@external')
@Field(() => ID)
_id: string;
}
extend type User @key(fields: "id") {
id: ID! @external
}
接着在 Resolver 中写一个解析栏位物件的一个方法
@ResolveField(() => User)
user(@Parent() task: Task) {
return { __typename: 'User', _id: task.userId };
}
以上我们就完成了在 gateway 中能利用 Task 的 userId ,到 User Service 中查询 User 并回传给 Task Service ,最终根据 Schema 的格式回传给 Client side
:::warning
在开始测试前,请读者先将之前的资料先全部清除,之前的 Task 并没有 userId 的栏位,所以无法查出 User 物件
:::
我们直接在 http://localhost:4000/graphql gateway 上做测试
先建立一个 User
mutation {
createUser(userData: { name: "JavaScript" }) {
_id
name
}
}
接着建立 Task
这边与之前不一样得部分是多了一个 userId ,如果刚刚的 User 回传的 _id 没有纪录,请读者到资料库去找一下吧!
回传时,我们也能取得 User 的物件
mutation {
createTask(taskData: {
title: "THE THING TO DO TODAY",
content: "THE THING Content"
userId: "5f840e6de88fe979392f010c"
}) {
_id
title
content
user {
name
_id
}
}
}
最後使用查询找出刚刚建立的 Task
query {
todoTasks {
tasks {
user {
name
_id
}
content
title
}
}
}
完美!!!!
>>: JavaScript 之旅 (27):Promise.any() & AggregateError
还记得先前提到 Math.random 并非是纯函式吗,因为每次给定相同的输入都会是不同的输出回传回...
此篇为前篇的延续唷! 方便阅读再贴一次基本的explain及测试表 mysql> explai...
第十二天罗~ 当更新画面 我们必须触发 React 的更新流程, 这样最新的资料才会显示在画面上, ...
前言 恭喜 codepen 复活 \(^∀^)メ(^∀^)ノ 终於可以透过实作来学习如何选取元素、操...
我的资料结构 . ├── App.js // App root component,the star...