@prefabs.tech/fastify-graphql
v0.94.0
Published
Fastify graphql plugin
Keywords
Readme
@prefabs.tech/fastify-graphql
A Fastify plugin that provides an easy integration of mercurius graphql server in a fastify API.
The plugin is a thin wrapper around the mercurius plugin.
Why this plugin?
While registering mercurius directly perfectly enables GraphQL in a Fastify backend, enterprise APIs require deep context injection—such as database connections and application configurations—to function effectively within resolvers. We created this plugin to:
- Automate Context Injection: Instead of manually building context objects on every request, this plugin automatically populates the
MercuriusContextwith thefastify.config,slonikdatabase connection, anddbSchema, making them instantly and safely available to all your GraphQL resolvers out-of-the-box. - Unify Configuration: By integrating seamlessly with
@prefabs.tech/fastify-config, it ensures that your GraphQL schema paths, options, and boolean flags are strictly typed and managed in one centralized location.
Design Decisions: Why not Apollo Server or bare Mercurius?
- Why Mercurius instead of Apollo: Mercurius is specifically built for Fastify, leveraging Fastify's lifecycle hooks to deliver significantly better performance and lower latency than typical Apollo setups.
- Why intercept Mercurius: Using bare Mercurius means maintaining your own context factory methods to inject database connections and app configurations recursively. By wrapping it, we enforce a standard, highly-typed context shape that is guaranteed to match the rest of our ecosystem, eliminating setup boilerplate completely.
Requirements
Installation
Install with npm:
npm install @prefabs.tech/fastify-config @prefabs.tech/fastify-graphql graphql mercuriusInstall with pnpm:
pnpm add --filter "@scope/project" @prefabs.tech/fastify-config @prefabs.tech/fastify-graphql graphql mercuriusUsage
To set up graphql in fastify project, follow these steps:
Create a resolvers file at src/graphql/resolvers.ts to define all GraphQL mutations and queries.
import type { IResolvers } from "mercurius";
const resolvers: IResolvers = {
Mutation: {
subtract: async (_, { x, y }) => x - y,
},
Query: {
add: async (_, { x, y }) => x + y,
},
};
export default resolvers;Create a schema file at src/graphql/schema.ts:
const schema = `
type Mutation {
subtract(x: Int, y: Int): Int
}
type Query {
add(x: Int, y: Int): Int
}
`;
export default schema;Export the resolvers and schema from the src/graphql/index.ts file:
export { default as resolvers } from "./resolvers";
export { default as schema } from "./schema";Add a graphql block to your config in config/index.ts:
import { parse } from "@prefabs.tech/fastify-config";
import dotenv from "dotenv";
import { resolvers, schema } from "../src/graphql";
import type { ApiConfig } from "@prefabs.tech/fastify-config";
dotenv.config();
const config: ApiConfig = {
// ...other configurations...
graphql: {
enabled: true,
graphiql: false,
path: "/graphql",
resolvers,
schema,
},
// ...other configurations...
};
export default config;Register the plugin with your fastify instance in src/index.ts:
import configPlugin from "@prefabs.tech/fastify-config";
import graphqlPlugin from "@prefabs.tech/fastify-graphql";
import Fastify from "fastify";
import config from "../config";
const start = async () => {
const fastify = Fastify({
logger: config.logger,
});
// Register fastify-config plugin
await fastify.register(configPlugin, { config });
// Register fastify-graphql plugin
await fastify.register(graphqlPlugin, config.graphql);
await fastify.listen({
port: config.port,
host: "0.0.0.0",
});
};
start();Configuration
The graphql block in the ApiConfig supports all of the original mercurius plugin's options.
An additional enabled (boolean) option allows you to disable the graphql server.
Context
The fastify-graphql plugin will generate a graphql context on every request that will include the following attributes:
| Attribute | Type | Description |
| ---------- | ----------- | ---------------------------------------------------------------------------------------- |
| config | ApiConfig | The fastify servers' config (as per @prefabs.tech/fastify-config) |
| database | Database | The fastify server's slonik instance (as per @prefabs.tech/fastify-slonik) |
| dbSchema | string | The database schema (as per @prefabs.tech/fastify-slonik) |
Supporting .gql files and external schema exports
To work with multiple schemas defined in .gql files or support GraphQL schema exports from external packages, ensure the following packages are installed in your API:
To load and merge your GraphQL schemas, update your src/graphql/schema.ts file as follows:
import { loadFilesSync } from "@graphql-tools/load-files";
import { mergeTypeDefs } from "@graphql-tools/merge";
import { makeExecutableSchema } from "@graphql-tools/schema";
const schemas: string[] = loadFilesSync("./src/**/*.gql");
const typeDefs = mergeTypeDefs(schemas);
const schema = makeExecutableSchema({ typeDefs });
export default schema;If you also need to include schemas defined in other packages update above code:
import { graphqlSchema } from "example"; // example: importing schemas from external packages
import { loadFilesSync } from "@graphql-tools/load-files";
import { mergeTypeDefs } from "@graphql-tools/merge";
import { makeExecutableSchema } from "@graphql-tools/schema";
const schemaFiles: string[] = loadFilesSync("./src/**/*.gql");
const typeDefs = mergeTypeDefs([graphqlSchema, ...schemaFiles]);
const schema = makeExecutableSchema({ typeDefs });
export default schema;You can define additional schemas within the src/ directory, including any nested subdirectories, using .gql files. For example, create a new file at src/graphql/schema.gql:
type Mutation {
subtract(x: Int, y: Int): Int
}
type Query {
add(x: Int, y: Int): Int
}