Skip to content

Commit

Permalink
Merge pull request #3171 from mattia-lau/fix/federation-interface-res…
Browse files Browse the repository at this point in the history
…olver

fix(apollo): federation interface resolver
  • Loading branch information
kamilmysliwiec authored Jul 2, 2024
2 parents 9d6b813 + 8b0802f commit 58114fc
Show file tree
Hide file tree
Showing 8 changed files with 102 additions and 3 deletions.
3 changes: 3 additions & 0 deletions packages/apollo/tests/code-first-federation/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,16 @@ import { PostModule } from './post/post.module';
import { RecipeModule } from './recipe/recipe.module';
import { User } from './user/user.entity';
import { UserModule } from './user/user.module';
import { HumanModule } from './human/human.module';

@Module({
imports: [
UserModule,
PostModule,
RecipeModule,
HumanModule,
GraphQLModule.forRoot<ApolloDriverConfig>({
inheritResolversFromInterfaces: true,
driver: ApolloFederationDriver,
includeStacktraceInErrorResponses: false,
autoSchemaFile: true,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Field, ID, InterfaceType } from '@nestjs/graphql';

@InterfaceType()
export abstract class Character {
@Field((type) => ID)
id: string;

@Field()
name: string;
}
10 changes: 10 additions & 0 deletions packages/apollo/tests/code-first-federation/human/human.entity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { ObjectType } from '@nestjs/graphql';
import { Character } from './character.entity';

@ObjectType({
implements: () => [Character],
})
export class Human implements Character {
id: string;
name: string;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { Module } from '@nestjs/common';
import { HumanResolver } from './human.resolver';

@Module({
providers: [HumanResolver],
})
export class HumanModule {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { Query, Resolver, ResolveField } from '@nestjs/graphql';
import { Human } from './human.entity';
import { Character } from './character.entity';

@Resolver(() => Character)
export class HumanResolver {
@Query(() => [Human])
humans(): Human[] {
return [
{ id: '1', name: 'Bob' },
{ id: '2', name: 'Alice' },
];
}

@ResolveField(() => [Human])
friends(): Human[] {
return [{ id: '3', name: 'Peter' }];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,24 @@ type Recipe implements IRecipe {
description: String!
}
type Human implements Character {
id: ID!
name: String!
friends: [Human!]!
}
interface Character {
id: ID!
name: String!
friends: [Human!]!
}
type Query {
findPost(id: Float!): Post!
getPosts: [Post!]!
search: [FederationSearchResultUnion!]! @deprecated(reason: "test")
recipe: IRecipe!
humans: [Human!]!
_entities(representations: [_Any!]!): [_Entity]!
_service: _Service!
}
Expand Down
31 changes: 31 additions & 0 deletions packages/apollo/tests/e2e/code-first-federation.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,37 @@ describe('Code-first - Federation', () => {
});
});

it('should return the human result with resolve interface', async () => {
const response = await apolloClient.executeOperation({
query: gql`
{
humans {
id
name
friends {
id
name
}
}
}
`,
});
expectSingleResult(response).toEqual({
humans: [
{
id: '1',
name: 'Bob',
friends: [{ id: '3', name: 'Peter' }],
},
{
id: '2',
name: 'Alice',
friends: [{ id: '3', name: 'Peter' }],
},
],
});
});

afterEach(async () => {
await app.close();
});
Expand Down
12 changes: 9 additions & 3 deletions packages/graphql/lib/federation/graphql-federation.factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,9 +139,15 @@ export class GraphQLFederationFactory {
typeDefs = typeDefsDecorator.decorate(typeDefs, federationOptions);
}

let executableSchema: GraphQLSchema = buildFederatedSchema({
typeDefs: gql(typeDefs),
resolvers: this.getResolvers(options.resolvers),
const resolvers = this.getResolvers(options.resolvers);
let executableSchema: GraphQLSchema = addResolversToSchema({
schema: buildFederatedSchema({
typeDefs: gql(typeDefs),
resolvers,
}),
resolvers,
resolverValidationOptions: options.resolverValidationOptions,
inheritResolversFromInterfaces: options.inheritResolversFromInterfaces,
});

executableSchema = this.overrideOrExtendResolvers(
Expand Down

0 comments on commit 58114fc

Please sign in to comment.