Federation
Davide Gheri edited this page Feb 19, 2021
·
2 revisions
Mercurius supports GraphQL Federation out of the box, but due to how this module interacts with Nestjs, a dependency of @apollo/federation
is still needed
npm i @apollo/federation
To make a Nestjs application e federation Service, pass federationMetadata: true
to MercuriusModuleOptions
Federation is tested only with code first approach
@Module({
imports: [
MercuriusModule.forRoot({
autoSchemaFile: true,
federationMetadata: true,
}),
],
})
Decorate your entities with federation directives:
@Directive('@key(fields: "id")')
@ObjectType()
export class User {
@Field(() => ID)
id: number;
}
Refer to Nestjs documentation for all options
To make a Nestjs application a federation Gateway, use the MercuriusGatewayModule
import { MercuriusGatewayModule } from 'nestjs-mercurius';
@Module({
imports: [
MercuriusGatewayModule.forRoot({
graphiql: 'playground',
subscription: true, // yes, Mercurius supports federation subscriptions
gateway: {
services: [
{
name: 'cats',
url: 'http://cats.local.svc/graphql',
wsUrl: 'ws://cats.local.svc/graphql',
mandatory: true,
},
{
name: 'dogs',
url: 'http://dogs.local.svc/graphql',
wsUrl: 'ws://dogs.local.svc/graphql',
mandatory: true,
},
]
}
})
]
})
All MercuriusGatewayModule
options:
/**
* Serve GraphiQL on /graphiql if true or 'graphiql', or GraphQL IDE on /playground if 'playground' and if routes is true
*/
graphiql?: boolean | string;
ide?: boolean | string;
/**
* The minimum number of execution a query needs to be executed before being jit'ed.
* @default true
*/
jit?: number;
/**
* A graphql endpoint is exposed at /graphql when true
* @default true
*/
routes?: boolean;
/**
* Define if the plugin can cache the responses.
* @default true
*/
cache?: boolean | number;
/**
* An endpoint for graphql if routes is true
* @default '/graphql'
*/
path?: string;
/**
* Change the route prefix of the graphql endpoint if set
*/
prefix?: string;
/**
* Add the empty Mutation definition if schema is not defined
* @default false
*/
defineMutation?: boolean;
/**
* Change the default error handler (Default: true).
* If a custom error handler is defined, it should return the standardized response format according to [GraphQL spec](https://graphql.org/learn/serving-over-http/#response).
* @default true
*/
errorHandler?:
| boolean
| ((error: FastifyError, request: FastifyRequest, reply: FastifyReply) => ExecutionResult);
/**
* Change the default error formatter.
*/
errorFormatter?: <TContext extends Record<string,any> = MercuriusContext>(
execution: ExecutionResult,
context: TContext
) => {
statusCode: number;
response: ExecutionResult;
};
/**
* The maximum depth allowed for a single query.
*/
queryDepth?: number;
context?: (
request: FastifyRequest,
reply: FastifyReply
) => Promise<Record<string, any>> | Record<string, any>;
/**
* Optional additional validation rules.
* Queries must satisfy these rules in addition to those defined by the GraphQL specification.
*/
validationRules?: ValidationRules;
/**
* Enable subscription support when options are provided. [`emitter`](https://github.com/mcollina/mqemitter) property is required when subscriptions is an object. (Default false)
*/
subscription?:
| boolean
| {
emitter?: object;
pubsub?: any; // FIXME: Technically this should be the PubSub type. But PubSub is now typed as SubscriptionContext.
verifyClient?: (
info: { origin: string; secure: boolean; req: IncomingMessage },
next: (
result: boolean,
code?: number,
message?: string,
headers?: OutgoingHttpHeaders
) => void
) => void;
context?: (
connection: SocketStream,
request: FastifyRequest
) => Record<string, any> | Promise<Record<string, any>>;
onConnect?: (data: {
type: 'connection_init';
payload: any;
}) => Record<string, any> | Promise<Record<string, any>>;
onDisconnect?: (context: MercuriusContext) => void | Promise<void>;
};
/**
* Persisted queries, overrides persistedQueryProvider.
*/
persistedQueries?: Record<string,string>;
/**
* Only allow persisted queries. Required persistedQueries, overrides persistedQueryProvider.
*/
onlyPersisted?: boolean;
/**
* Settings for enabling persisted queries.
*/
persistedQueryProvider?: mercurius.PersistedQueryProvider;
/**
* Enable support for batched queries (POST requests only).
* Batched query support allows clients to send an array of queries and
* receive an array of responses within a single request.
*/
allowBatchedQueries?: boolean;
/**
* Settings for GraphQL Playground. These settings only apply if `graphiql` parameter is set to 'playground'.
* The most current GraphQL Playground code is loaded via CDN, so new configuration settings may be available.
* See https://github.com/prisma-labs/graphql-playground#usage for the most up-to-date list.
*/
playgroundSettings?: {
['editor.cursorShape']: 'line' | 'block' | 'underline';
['editor.fontFamily']: string;
['editor.fontSize']: number;
['editor.reuseHeaders']: boolean;
['editor.theme']: 'dark' | 'light';
['general.betaUpdates']: boolean;
['prettier.printWidth']: number;
['prettier.tabWidth']: number;
['prettier.useTabs']: boolean;
['request.credentials']: 'omit' | 'include' | 'same-origin';
['schema.disableComments']: boolean;
['schema.polling.enable']: boolean;
['schema.polling.endpointFilter']: string;
['schema.polling.interval']: number;
['tracing.hideTracingResponse']: boolean;
['tracing.tracingSupported']: boolean;
};
/**
* It provides HTTP headers to GraphQL Playground. If it is an object,
* it is provided as-is. If it is a function, it is serialized, injected
* in the generated HTML and invoked with the `window` object as the argument.
* Useful to read authorization token from browser's storage.
* See [examples/playground.js](https://github.com/mercurius-js/mercurius/blob/master/examples/playground.js).
*/
playgroundHeaders?: ((window: Window) => object) | object;
useGlobalPrefix?: boolean;
uploads?: boolean | FileUploadOptions;
altair?: boolean | import('altair-fastify-plugin').AltairFastifyPluginOptions;
gateway: {
services: Array<MercuriusGatewayService>;
pollingInterval?: number;
errorHandler?(error: Error, service: MercuriusGatewayService): void
};