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.
Install with npm:
npm install @dzangolab/fastify-config @dzangolab/fastify-graphql graphql mercurius
Install with pnpm:
pnpm add --filter "@scope/project" @dzangolab/fastify-config @dzangolab/fastify-graphql graphql mercurius
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 "@dzangolab/fastify-config";
import dotenv from "dotenv";
import { resolvers, schema } from "../src/graphql";
import type { ApiConfig } from "@dzangolab/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 "@dzangolab/fastify-config";
import graphqlPlugin from "@dzangolab/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();
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.
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 @dzangolab/fastify-config) |
database |
Database |
The fastify server's slonik instance (as per @dzangolab/fastify-slonik) |
dbSchema |
string |
The database schema (as per @dzangolab/fastify-slonik) |
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
}