or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

federation.mdindex.mdmodule-configuration.mdresolvers.mdschema-building.mdschema-decorators.mdservices.mdsubscriptions.mdtype-system.md

federation.mddocs/

0

# Federation Support

1

2

Apollo Federation capabilities for building distributed GraphQL architectures with reference resolvers and federated schema generation. This module enables creating microservice-based GraphQL systems where multiple services contribute to a unified GraphQL schema.

3

4

## Capabilities

5

6

### Federation Factory

7

8

Core factory service for creating federated GraphQL schemas that can be combined with other federated services.

9

10

```typescript { .api }

11

/**

12

* Injectable factory for creating federated GraphQL schemas

13

* Extends GraphQLFactory with federation-specific capabilities

14

*/

15

export class GraphQLFederationFactory {

16

/**

17

* Merge the generated schema with an existing federated schema

18

* @param schema - Existing GraphQL schema to merge with

19

* @returns Merged federated schema

20

*/

21

mergeWithSchema(schema: GraphQLSchema): GraphQLSchema;

22

23

/**

24

* Create a federated schema from module options

25

* @param options - GraphQL module configuration options

26

* @returns Promise resolving to federated GraphQL schema

27

*/

28

create(options: GqlModuleOptions): Promise<GraphQLSchema>;

29

30

/**

31

* Transform a regular schema into a federated subgraph schema

32

* @param schema - Regular GraphQL schema

33

* @returns Federated subgraph schema

34

*/

35

transformSchemaToFederated(schema: GraphQLSchema): GraphQLSchema;

36

}

37

```

38

39

**Usage Examples:**

40

41

```typescript

42

import { Module } from "@nestjs/common";

43

import { GraphQLFederationModule } from "@nestjs/graphql";

44

import { ApolloFederationDriver, ApolloFederationDriverConfig } from "@nestjs/apollo";

45

46

// Configure federated GraphQL module

47

@Module({

48

imports: [

49

GraphQLFederationModule.forRoot<ApolloFederationDriverConfig>({

50

driver: ApolloFederationDriver,

51

autoSchemaFile: {

52

federation: 2, // Use Apollo Federation v2

53

},

54

}),

55

],

56

providers: [UserResolver, PostResolver],

57

})

58

export class FederatedAppModule {}

59

60

// Async federation configuration

61

@Module({

62

imports: [

63

GraphQLFederationModule.forRootAsync<ApolloFederationDriverConfig>({

64

driver: ApolloFederationDriver,

65

useFactory: (configService: ConfigService) => ({

66

autoSchemaFile: {

67

federation: 2,

68

path: configService.get('SCHEMA_PATH'),

69

},

70

buildSchemaOptions: {

71

orphanedTypes: [User, Post], // Include federated entities

72

},

73

}),

74

inject: [ConfigService],

75

}),

76

],

77

})

78

export class AsyncFederatedAppModule {}

79

```

80

81

### Federation Definitions Factory

82

83

Factory for generating TypeScript definitions from federated GraphQL schemas.

84

85

```typescript { .api }

86

/**

87

* Factory for generating federation-specific TypeScript definitions

88

* Handles federated schema elements like entities and references

89

*/

90

export class GraphQLFederationDefinitionsFactory {

91

/**

92

* Generate TypeScript definitions from federated schema

93

* @param options - Options for definition generation

94

* @returns Promise that resolves when generation is complete

95

*/

96

generate(options: FederationDefinitionsGeneratorOptions): Promise<void>;

97

98

/**

99

* Generate federated entity interfaces

100

* @param schema - Federated GraphQL schema

101

* @returns Generated TypeScript interface definitions

102

*/

103

generateEntityInterfaces(schema: GraphQLSchema): string;

104

105

/**

106

* Generate reference resolver types

107

* @param schema - Federated GraphQL schema

108

* @returns Generated TypeScript type definitions for reference resolvers

109

*/

110

generateReferenceTypes(schema: GraphQLSchema): string;

111

}

112

113

/**

114

* Options for federated definitions generation

115

*/

116

interface FederationDefinitionsGeneratorOptions extends DefinitionsGeneratorOptions {

117

/** Whether to generate entity interfaces */

118

generateEntityInterfaces?: boolean;

119

/** Whether to generate reference resolver types */

120

generateReferenceTypes?: boolean;

121

/** Federation version (1 or 2) */

122

federationVersion?: 1 | 2;

123

}

124

```

125

126

### Reference Resolvers

127

128

Decorators and utilities for implementing entity reference resolution in federated schemas.

129

130

```typescript { .api }

131

/**

132

* Marks a method as a GraphQL Reference Resolver for Apollo Federation

133

* Used to resolve entity references across federated services

134

*/

135

function ResolveReference(): MethodDecorator;

136

137

/**

138

* Interface for federation reference objects

139

*/

140

interface FederationReference {

141

/** GraphQL type name */

142

__typename: string;

143

/** Entity identifier fields */

144

[key: string]: any;

145

}

146

147

/**

148

* Type for reference resolver functions

149

*/

150

type ReferenceResolverFn<T = any> = (

151

reference: FederationReference

152

) => T | Promise<T>;

153

```

154

155

**Usage Examples:**

156

157

```typescript

158

import { Resolver, ResolveReference, Directive, ObjectType, Field, ID } from "@nestjs/graphql";

159

160

// Define federated entity

161

@ObjectType()

162

@Directive('@key(fields: "id")')

163

export class User {

164

@Field(() => ID)

165

id: string;

166

167

@Field()

168

name: string;

169

170

@Field()

171

email: string;

172

173

// External field from another service

174

@Field(() => [Post])

175

@Directive('@external')

176

posts: Post[];

177

}

178

179

// Resolver with reference resolver

180

@Resolver(() => User)

181

export class UserResolver {

182

constructor(private userService: UserService) {}

183

184

// Standard queries

185

@Query(() => [User])

186

users(): Promise<User[]> {

187

return this.userService.findAll();

188

}

189

190

// Federation reference resolver

191

@ResolveReference()

192

async resolveReference(reference: { __typename: string; id: string }): Promise<User> {

193

return this.userService.findById(reference.id);

194

}

195

196

// Field resolver for federated field

197

@ResolveField(() => String)

198

displayName(@Parent() user: User): string {

199

return `${user.name} (${user.email})`;

200

}

201

}

202

203

// Extending external entity from another service

204

@ObjectType()

205

@Directive('@extends')

206

@Directive('@key(fields: "id")')

207

export class Post {

208

@Field(() => ID)

209

@Directive('@external')

210

id: string;

211

212

// Add new field to external entity

213

@Field(() => Int)

214

viewCount: number;

215

216

// Field from owning service

217

@Field()

218

@Directive('@external')

219

title: string;

220

}

221

222

@Resolver(() => Post)

223

export class PostResolver {

224

constructor(private analyticsService: AnalyticsService) {}

225

226

@ResolveReference()

227

resolveReference(reference: { __typename: string; id: string }): Post {

228

// Return minimal object with external fields

229

return { id: reference.id } as Post;

230

}

231

232

@ResolveField(() => Int)

233

async viewCount(@Parent() post: Post): Promise<number> {

234

return this.analyticsService.getViewCount(post.id);

235

}

236

}

237

```

238

239

### Federation Directives

240

241

GraphQL directives used in Apollo Federation for schema composition.

242

243

```typescript { .api }

244

/**

245

* Key directive - marks fields that uniquely identify an entity

246

* @param fields - Field names that form the key

247

*/

248

const KeyDirective = '@key(fields: string)';

249

250

/**

251

* External directive - marks fields that are owned by another service

252

*/

253

const ExternalDirective = '@external';

254

255

/**

256

* Requires directive - specifies external fields needed to resolve a field

257

* @param fields - External field names required

258

*/

259

const RequiresDirective = '@requires(fields: string)';

260

261

/**

262

* Provides directive - specifies external fields that this field can provide

263

* @param fields - External field names provided

264

*/

265

const ProvidesDirective = '@provides(fields: string)';

266

267

/**

268

* Extends directive - indicates that this type extends an entity from another service

269

*/

270

const ExtendsDirective = '@extends';

271

272

/**

273

* Shareable directive (Federation v2) - marks fields that can be resolved by multiple services

274

*/

275

const ShareableDirective = '@shareable';

276

277

/**

278

* Override directive (Federation v2) - overrides field resolution from another service

279

* @param from - Service name to override from

280

*/

281

const OverrideDirective = '@override(from: string)';

282

```

283

284

**Federation Directive Examples:**

285

286

```typescript

287

import { ObjectType, Field, ID, Directive } from "@nestjs/graphql";

288

289

// Entity with composite key

290

@ObjectType()

291

@Directive('@key(fields: "id")')

292

@Directive('@key(fields: "email")')

293

export class User {

294

@Field(() => ID)

295

id: string;

296

297

@Field()

298

email: string;

299

300

@Field()

301

name: string;

302

}

303

304

// Extending external entity with requirements

305

@ObjectType()

306

@Directive('@extends')

307

@Directive('@key(fields: "id")')

308

export class Product {

309

@Field(() => ID)

310

@Directive('@external')

311

id: string;

312

313

@Field()

314

@Directive('@external')

315

name: string;

316

317

@Field()

318

@Directive('@external')

319

price: number;

320

321

// This field requires external fields

322

@Field()

323

@Directive('@requires(fields: "name price")')

324

displayPrice: string;

325

}

326

327

// Federation v2 shareable field

328

@ObjectType()

329

@Directive('@key(fields: "id")')

330

export class User {

331

@Field(() => ID)

332

id: string;

333

334

@Field()

335

@Directive('@shareable')

336

name: string; // Can be resolved by multiple services

337

338

@Field()

339

@Directive('@override(from: "legacy-service")')

340

email: string; // Override resolution from legacy service

341

}

342

```

343

344

### Federation Configuration

345

346

Configuration options specific to federated GraphQL schemas.

347

348

```typescript { .api }

349

/**

350

* Federation-specific module options

351

*/

352

interface FederationGqlModuleOptions extends GqlModuleOptions {

353

/** Auto schema file configuration for federation */

354

autoSchemaFile?: boolean | FederationAutoSchemaFileConfig;

355

356

/** Federation version to use */

357

federationVersion?: 1 | 2;

358

359

/** Whether to print federated schema SDL */

360

printFederatedSchema?: boolean;

361

}

362

363

/**

364

* Auto schema file configuration for federation

365

*/

366

interface FederationAutoSchemaFileConfig {

367

/** Path to write the federated schema */

368

path?: string;

369

/** Federation version */

370

federation?: 1 | 2;

371

}

372

373

/**

374

* Build schema options with federation support

375

*/

376

interface FederationBuildSchemaOptions extends BuildSchemaOptions {

377

/** Federation version */

378

federationVersion?: 1 | 2;

379

/** Whether to include federation directives */

380

includeFederationDirectives?: boolean;

381

}

382

```

383

384

### Federation Gateway Integration

385

386

Utilities for integrating with Apollo Federation Gateway.

387

388

```typescript { .api }

389

/**

390

* Configuration for Apollo Federation Gateway integration

391

*/

392

interface FederationGatewayConfig {

393

/** List of federated services */

394

serviceList: FederatedService[];

395

/** Enable managed federation */

396

managed?: boolean;

397

/** Schema registry configuration */

398

schemaConfigDeliveryEndpoint?: string;

399

}

400

401

/**

402

* Federated service configuration

403

*/

404

interface FederatedService {

405

/** Service name */

406

name: string;

407

/** Service GraphQL endpoint URL */

408

url: string;

409

/** Optional headers for service requests */

410

headers?: Record<string, string>;

411

}

412

```

413

414

**Gateway Integration Example:**

415

416

```typescript

417

import { ApolloGateway } from "@apollo/gateway";

418

import { ApolloServer } from "apollo-server-express";

419

420

// Configure federation gateway

421

const gateway = new ApolloGateway({

422

serviceList: [

423

{ name: 'users', url: 'http://localhost:4001/graphql' },

424

{ name: 'posts', url: 'http://localhost:4002/graphql' },

425

{ name: 'comments', url: 'http://localhost:4003/graphql' },

426

],

427

});

428

429

// Create Apollo Server with gateway

430

const server = new ApolloServer({

431

gateway,

432

subscriptions: false, // Subscriptions not supported in federation

433

});

434

435

// Start federated gateway

436

server.listen({ port: 4000 }).then(({ url }) => {

437

console.log(`๐Ÿš€ Federation Gateway ready at ${url}`);

438

});

439

```

440

441

### Error Handling in Federation

442

443

Best practices for handling errors in federated GraphQL architectures.

444

445

```typescript { .api }

446

/**

447

* Federation-specific error types

448

*/

449

interface FederationError extends GraphQLError {

450

/** Service that generated the error */

451

service?: string;

452

/** Whether error should be propagated to parent */

453

propagate?: boolean;

454

}

455

456

/**

457

* Error handling options for federation

458

*/

459

interface FederationErrorHandling {

460

/** How to handle service unavailability */

461

serviceUnavailable?: 'fail' | 'partial' | 'ignore';

462

/** Timeout for service requests */

463

timeout?: number;

464

/** Retry configuration */

465

retry?: {

466

attempts: number;

467

delay: number;

468

};

469

}

470

```