Fastify is a plugin-based, highly efficient and, developer-friendly Nodejs framework inspired by Hapi and Express. However, it offers better performance with low overhead. Fastify shines when it comes to building fast HTTP server, and benchmark shows that in some cases it performs nearly three times faster than Express.
Also, Fastify uses an extremely fast radix tree, based HTTP router called find-my-way which performs more operations per second compared to its alternatives. Here is benchmark for the most commonly used routers. Fastify is a very modular system that is fully extensible with hooks, plugins and, decorators. In this article, we would be looking at how to integrate Fastify with GraphQL.
GraphQL — Graph Query Language, is a query language for APIs and a runtime for fulfilling those queries with your existing data. GraphQL creates fast and flexible APIs and gives the client complete control to describe what data they need — as opposed to traditional REST API endpoints where the server determines what is returned. Consequently, with GraphQL, we get fewer HTTP requests, flexible data querying, and less code to manage. Also, like REST, GraphQL operates over HTTP, so we can use it with any database, backend language, or client.
In this article, we would be building APIs for a blog using Fastify and GraphQL.
Out of the box, Fastify does not support GraphQL but we can easily add GraphQL support by using the mercurius plugin. Mercurius is a GraphQL adapter for Fastify; it provides GraphQL integration with caching of both query parsing and validation. Also, it provides a Just-In-Time compiler via graphql-jit and an automatic loader integration to avoid 1 + N queries. We will learn more about mercurius as we build our blog APIs; in the subsequent section. Let’s get started with the prerequisites.
To follow along in this article, here are a few prerequisites to note:
- Node.js and MongoDB installed.
- Basic knowledge of MongoDB and Mongoose.
To get started, we need to set up our server.
Follow the steps below to create the server:
- Create an npm project and install all the needed dependencies:
- Enable es6 modules:
While tools like Babel have been long used to achieve this, we will use simpler solutions in this article. Simply add the following code to your package.json file — if you have Node version 12 and above installed.
However, if you have Node version 8 or 10 you can enable this feature by using esm.
- Add our scripts:
Open the package.json file and edit the scripts section as follows:
- "start": "node --es-module-specifier-resolution=node src/index.js" is the production command to start our server it uses node.
- "dev": "nodemon --es-module-specifier-resolution=node ./src/index.js" uses nodemon to restart our server any time we compile our code.
The --es-module-specifier-resolution=node is required to aid interoperability between the es module — ESM and Node’s commonJS modules. The current ESM specifier resolution does not support all the features of the commonJS loader. A key difference is the automatic resolution of file extensions and the ability to import directories that have an index file.
However, we can customize the ESM specifier resolution algorithm by adding the --es-module-specifier-resolution=node flag.
- Setup our server:
In the root directory, create a src directory with an index.js file containing the following code:
Now we can start the server by running npm run dev the outputs:
Great our server is working. Let’s start building our blog APIs with GraphQL in the next section.
Building GraphQL APIs
To get started we need to build our data models and connect our application to MongoDB.
In the src directory create a config directory with an index.js file and a models, directory. Inside the models directory, create a post.js file with the following codes:
Connecting to MongoDB using Mongoose
In the index.js file in the config directory add the following code:
The code above connects our app to MongoDB using mongoose and logs the connection status to the console. Also, we decorate Fastify with our models to foster code reuse. After creating the Fastify plugin above, to connect our application to MongoDB, we need to create our GraphQL schema and resolvers.
Setup GraphQL schema and resolvers
In other to add GraphQL support to our app, mercurius takes two plugin options namely schema, resolvers, and graphiql — you can get a complete list of plugin options here. The schema option is a string — that would be parsed or the schema definition. It takes our GraphQL schema as its value. The resolvers option is an object that takes our resolvers as its value. The graphiql option takes a String or a Boolean. It would serve GraphiQL on /graphiql if true. Also, we can pass a string Playground to serve GraphiQL on /playground. Inside the src directory create a graphql folder and create a schema.js file in it.
Add the following code to the schema.js file:
The code above contains our GraphQL schema.
Also, create a resolvers.js file inside the graphql folder and add the following code to it:
Resolvers are functions that are responsible for populating the data for a single field in our schema. Resolvers respond to client requests by fetches the requested data from the appropriate data source. Our resolvers above take two objects as parameters — - and obj. Our query arguments are available in the obj parameter hence we can destructure our data from them as seen in our Mutation.
Finally, to get all this working, we need to register our Fastify plugins.
Register Fastify Plugins
Import in the index.js file, we import all our Fastify plugins as seen below:
Then we active these plugins by adding the following codes below the
// Active plugins below:
The code above registers our db plugin which connects our app to MongoDB. And also, registers the mercurius plugin which adds GraphQL support to our application.
Now when we can test our server by running:
Also, we can access the GraphQL playground to test our APIs by visiting http://localhost:4500/playground with our browser.
In this article, we would test our GraphQL APIs using curl and jq.
Both Fastify and GraphQL are great technologies that offer improved speed, flexibility, and easy code maintainability. The Fastify GraphQL adapter mercurius adds GraphQL support to Fastify. It also supports TypeScript by using TypeGraphQL. This allows you to follow a code-first approach instead of the SDL first.
A full working example of our blog APIs is available on Github. And I hope after this article you are ready to start building modern APIs with Fastify and GraphQL.