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
+197-3Lines changed: 197 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -21,6 +21,8 @@ First install the optional dependency for federation:
21
21
$ npm install --save @apollo/federation
22
22
```
23
23
24
+
##### Schema first
25
+
24
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.
25
27
26
28
```graphql
@@ -74,8 +76,76 @@ import { UsersResolvers } from './users.resolvers';
74
76
exportclassAppModule {}
75
77
```
76
78
79
+
##### Code first
80
+
81
+
Code first federation is very similar to regular code first GraphQL. We simply add some extra decorators to the `User` entity.
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
131
+
132
+
@Module({
133
+
imports: [
134
+
GraphQLFederationModule.forRoot({
135
+
autoSchemaFile: true,
136
+
}),
137
+
],
138
+
providers: [UsersResolvers, UsersService],
139
+
})
140
+
exportclassAppModule {}
141
+
```
142
+
77
143
#### Federated example: Posts
78
144
145
+
Our Post service serves aggregated posts via a `getPosts` query, but also extends our `User` type with `user.posts`
146
+
147
+
##### Schema first
148
+
79
149
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';
172
+
import { Query, Resolver, Parent, ResolveField } from '@nestjs/graphql';
103
173
import { PostsService } from './posts.service';
104
174
import { Post } from './posts.interfaces';
105
175
@@ -112,7 +182,7 @@ export class PostsResolvers {
112
182
returnthis.postsService.findAll();
113
183
}
114
184
115
-
@ResolveProperty('user')
185
+
@ResolveField('user')
116
186
getUser(@Parent() post: Post) {
117
187
return { __typename: 'User', id: post.userId };
118
188
}
@@ -137,11 +207,135 @@ import { PostsResolvers } from './posts.resolvers';
137
207
exportclassAppModule {}
138
208
```
139
209
210
+
##### Code first
211
+
212
+
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.
213
+
214
+
```ts
215
+
import { Directive, ObjectType, Field, ID } from'@nestjs/graphql';
216
+
import { Post } from'./post.entity';
217
+
218
+
@ObjectType()
219
+
@Directive('@extends')
220
+
@Directive('@key(fields: "id")')
221
+
exportclassUser {
222
+
@Field(type=>ID)
223
+
@Directive('@external')
224
+
public id:number;
225
+
226
+
@Field(type=> [Post])
227
+
public posts?:Post[];
228
+
229
+
constructor(user:Partial<User>) {
230
+
Object.assign(this, user);
231
+
}
232
+
}
233
+
```
234
+
235
+
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`.
143
337
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:
338
+
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:
0 commit comments