You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: content/graphql/federation.md
+191-9Lines changed: 191 additions & 9 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -15,13 +15,15 @@ In the next example, we'll set up a demo application with a gateway and two fede
15
15
16
16
#### Federated example: Users
17
17
18
-
First install the optional dependency for federation:
18
+
First, install the optional dependency for federation:
19
19
20
20
```bash
21
21
$ npm install --save @apollo/federation
22
22
```
23
23
24
-
The User service has a simple schema. Note the `@key` directive: it tells the Apollo query planner that a particular instance of User can be fetched if you have its `id`. Also note that we extend the `Query` type.
24
+
#### Schema first
25
+
26
+
The User service has a simple schema. Note the `@key` directive: it tells the Apollo query planner that a particular instance of User can be fetched if you have its `id`. Also, note that we extend the `Query` type.
Our resolver has one extra method: `resolveReference()`. It's called by the Apollo Gateway whenever a related resource requires a `User` instance. We'll see an example of this in the Posts service later on. Please note the `@ResolveReference()` decorator.
Finally, we hook everything up in a module together with a `GraphQLFederationModule`. This module accepts the same options as the regular `GraphQLModule`.
import { UsersService } from'./users.service'; // Not included in this example
127
+
128
+
@Module({
129
+
imports: [
130
+
GraphQLFederationModule.forRoot({
131
+
autoSchemaFile: true,
132
+
}),
133
+
],
134
+
providers: [UsersResolvers, UsersService],
135
+
})
136
+
exportclassAppModule {}
137
+
```
138
+
77
139
#### Federated example: Posts
78
140
141
+
Our Post service serves aggregated posts via a `getPosts` query, but also extends our `User` type with `user.posts`
142
+
143
+
#### Schema first
144
+
79
145
The Posts service references the User type in its schema by marking it with the `extend` keyword. It also adds one property to the User type. Note the `@key` directive used for matching instances of User, and the `@external` directive indicating that the `id` field is managed elsewhere.
import { Query, Resolver, Parent, ResolveProperty } from '@nestjs/graphql';
168
+
import { Query, Resolver, Parent, ResolveField } from '@nestjs/graphql';
103
169
import { PostsService } from './posts.service';
104
170
import { Post } from './posts.interfaces';
105
171
@@ -112,7 +178,7 @@ export class PostsResolvers {
112
178
returnthis.postsService.findAll();
113
179
}
114
180
115
-
@ResolveProperty('user')
181
+
@ResolveField('user')
116
182
getUser(@Parent() post: Post) {
117
183
return { __typename: 'User', id: post.userId };
118
184
}
@@ -137,11 +203,127 @@ import { PostsResolvers } from './posts.resolvers';
137
203
exportclassAppModule {}
138
204
```
139
205
206
+
##### Code first
207
+
208
+
We will need to create a class representing our `User` entity. Even though it lives in another service, we will be using and extending it. Note the `@extends` and `@external` directives.
209
+
210
+
```ts
211
+
import { Directive, ObjectType, Field, ID } from'@nestjs/graphql';
212
+
import { Post } from'./post.entity';
213
+
214
+
@ObjectType()
215
+
@Directive('@extends')
216
+
@Directive('@key(fields: "id")')
217
+
exportclassUser {
218
+
@Field((type) =>ID)
219
+
@Directive('@external')
220
+
id:number;
221
+
222
+
@Field((type) => [Post])
223
+
posts?:Post[];
224
+
}
225
+
```
226
+
227
+
We create the resolver for our extension on the `User` entity as follows:
First install the optional dependency for the gateway: `npm install --save @apollo/gateway`.
324
+
First, install the optional dependency for the gateway: `npm install --save @apollo/gateway`.
143
325
144
-
Our gateway only needs a list of endpoints and will auto-discover the schemas from there. The code for our gateway is therefore very short:
326
+
Our gateway only needs a list of endpoints and will auto-discover the schemas from there. Therefore it is the same for code and schema first, and the code for our gateway is very short:
145
327
146
328
```typescript
147
329
import { Module } from'@nestjs/common';
@@ -193,7 +375,7 @@ class AuthenticatedDataSource extends RemoteGraphQLDataSource {
0 commit comments