Skip to content

Commit 4a2ca54

Browse files
author
Elies Lou
committed
test(apollo-federation): added a multigraph use-case
1 parent 5b2fcd7 commit 4a2ca54

File tree

11 files changed

+397
-0
lines changed

11 files changed

+397
-0
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { Module } from '@nestjs/common';
2+
import { PostModule } from './post/post.module';
3+
import { UserModule } from './user/user.module';
4+
5+
@Module({
6+
imports: [PostModule, UserModule],
7+
})
8+
export class ApplicationModule {}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { Module } from '@nestjs/common';
2+
import { GqlModuleOptions, GraphQLModule } from '@nestjs/graphql';
3+
import { ApolloGatewayDriver, ApolloGatewayDriverConfig } from '../../lib';
4+
5+
@Module({
6+
imports: [
7+
GraphQLModule.forRoot<ApolloGatewayDriverConfig & GqlModuleOptions>({
8+
driver: ApolloGatewayDriver,
9+
gateway: {
10+
serviceList: [
11+
{ name: 'user', url: 'http://localhost:3000/user/graphql' },
12+
{ name: 'post', url: 'http://localhost:3000/post/graphql' },
13+
],
14+
},
15+
}),
16+
],
17+
})
18+
export class GatewayModule {}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { ValidationPipe } from '@nestjs/common';
2+
import { NestFactory } from '@nestjs/core';
3+
import { ApplicationModule } from './app.module';
4+
import { GatewayModule } from './gateway.module';
5+
6+
export async function bootstrap() {
7+
const app = await NestFactory.create(ApplicationModule);
8+
app.useGlobalPipes(new ValidationPipe());
9+
await app.listen(3000);
10+
11+
const gateway = await NestFactory.create(GatewayModule);
12+
await gateway.listen(3001);
13+
}
14+
15+
bootstrap();
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { Resolver, ResolveField, Parent } from '@nestjs/graphql';
2+
3+
import { Post, Publication } from '../post.type';
4+
import { User } from './user.type';
5+
6+
@Resolver(() => User)
7+
export class UserResolver {
8+
@ResolveField('posts', () => [Post])
9+
userPosts(@Parent() user: User): Post[] {
10+
return [
11+
{ id: 10, authorId: user.id, status: Publication.DRAFT, title: 'test' },
12+
];
13+
}
14+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { ObjectType, Directive, Field, ID } from '@nestjs/graphql';
2+
3+
@ObjectType()
4+
@Directive('@extends')
5+
@Directive('@key(fields: "id")')
6+
export class User {
7+
@Field(() => ID)
8+
@Directive('@external')
9+
id: number;
10+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { Module } from '@nestjs/common';
2+
import { GraphQLModule } from '@nestjs/graphql';
3+
4+
import { ApolloDriverConfig } from '../../../lib';
5+
import { ApolloFederationDriver } from '../../../lib/drivers';
6+
7+
import { UserResolver } from './external-user/user.resolver';
8+
import { PostResolver } from './post.resolver';
9+
10+
@Module({
11+
imports: [
12+
GraphQLModule.forRoot<ApolloDriverConfig>({
13+
driver: ApolloFederationDriver,
14+
debug: false,
15+
autoSchemaFile: true,
16+
path: '/post/graphql',
17+
include: [PostModule],
18+
}),
19+
],
20+
providers: [PostResolver, UserResolver],
21+
})
22+
export class PostModule {}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import {
2+
Resolver,
3+
Query,
4+
ResolveField,
5+
Parent,
6+
ID,
7+
Args,
8+
} from '@nestjs/graphql';
9+
10+
import { User } from './external-user/user.type';
11+
import { Post, Publication } from './post.type';
12+
13+
@Resolver(() => Post)
14+
export class PostResolver {
15+
store = new Set<Post>([
16+
{
17+
id: 1,
18+
authorId: 1,
19+
title: 'How to Jedi II',
20+
status: Publication.PUBLISHED,
21+
},
22+
{
23+
id: 2,
24+
authorId: 2,
25+
title: 'Why lightsabers are unreliable',
26+
status: Publication.DRAFT,
27+
},
28+
]);
29+
30+
@Query(() => [Post])
31+
posts() {
32+
return [...this.store];
33+
}
34+
35+
@Query(() => [Post])
36+
post(@Args('id', { type: () => ID }) id: number): Post | undefined {
37+
for (const post of this.store) {
38+
if (post.id.toString() === id.toString()) {
39+
return post;
40+
}
41+
}
42+
}
43+
44+
@ResolveField(() => User)
45+
user(@Parent() post: Post) {
46+
return { __typename: 'User', id: post.authorId };
47+
}
48+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import {
2+
registerEnumType,
3+
ObjectType,
4+
Directive,
5+
Field,
6+
ID,
7+
} from '@nestjs/graphql';
8+
9+
export enum Publication {
10+
PUBLISHED,
11+
DRAFT,
12+
}
13+
14+
registerEnumType(Publication, { name: 'Publication' });
15+
16+
@ObjectType()
17+
@Directive('@key(fields: "id")')
18+
export class Post {
19+
@Field(() => ID)
20+
id: number;
21+
22+
@Field()
23+
title: string;
24+
25+
@Field(() => Publication)
26+
status: Publication;
27+
28+
@Field(() => ID)
29+
authorId: number;
30+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { Module } from '@nestjs/common';
2+
import { GraphQLModule } from '@nestjs/graphql';
3+
4+
import { ApolloDriverConfig } from '../../../lib';
5+
import { ApolloFederationDriver } from '../../../lib/drivers';
6+
7+
import { UserResolver } from './user.resolver';
8+
9+
@Module({
10+
imports: [
11+
GraphQLModule.forRoot<ApolloDriverConfig>({
12+
driver: ApolloFederationDriver,
13+
debug: false,
14+
autoSchemaFile: true,
15+
path: '/user/graphql',
16+
include: [UserModule],
17+
}),
18+
],
19+
providers: [UserResolver],
20+
})
21+
export class UserModule {}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import {
2+
Field,
3+
ObjectType,
4+
Resolver,
5+
Query,
6+
ID,
7+
Directive,
8+
Args,
9+
ResolveReference,
10+
} from '@nestjs/graphql';
11+
12+
@ObjectType()
13+
@Directive('@key(fields: "id")')
14+
class User {
15+
@Field(() => ID)
16+
id: number;
17+
18+
@Field()
19+
name: string;
20+
}
21+
22+
@Resolver(() => User)
23+
export class UserResolver {
24+
private readonly store = new Set<User>([
25+
{ id: 1, name: 'Luke' },
26+
{ id: 2, name: 'Han' },
27+
]);
28+
29+
@Query(() => [User])
30+
users(): User[] {
31+
return [...this.store];
32+
}
33+
34+
@Query(() => User)
35+
user(@Args('id', { type: () => ID }) id: number): User | undefined {
36+
for (const user of this.store) {
37+
if (user.id.toString() === id.toString()) {
38+
return user;
39+
}
40+
}
41+
}
42+
43+
@ResolveReference()
44+
resolveReference(reference: {
45+
__typename: string;
46+
id: number;
47+
}): User | undefined {
48+
return this.user(reference.id);
49+
}
50+
}

0 commit comments

Comments
 (0)