📈 Why Work on a New GraphQL API Stack? #
Here I talk a little about a Fastify GraphQL API stack I have assembled and some choices made. This stack is something I will use as a staring point for new node backends which I want to interface with using GraphQL queries. I had previously used something based on a 14-hour Ben Awad YouTube tutorial. That tutorial turns two years old this week and has amassed an impressive 1.1 million views over that time. However, two years is a long time in tech, and over that time I have swapped out parts as newer tools got introduced. The latest change saw me swap out TypeGraphQL for Nexus. TypeGraphQL was just about one of the few remaining original components and needed a bit of refactoring. For those reasons, it seemed a good time to put together a fresh demo repo.
The original stack was Node Express, TypeScript, Apollo, PostgreSQL, TypeORM and TypeGraphQL. My latest incarnation still has TypeScript and PostgreSQL but uses Fastify as a node server, Mercurius (from the Fastify team) as the GraphQL server, Prisma (replacing TypeORM) and Nexus instead of TypeGraphQL. I also use uvu for unit testing. I’ll talk a little about what the elements bring to the party, but if you just want to see the code, it’s on the Rodney Lab GitHub repo (link further down the page).
🧑🏽🦼 Fastify #
Fastify forms the foundations of the stack. It is built to be a highly performant node server and an alternative to Express. As well as being fast, fastify has an extensive ecosystem of over 200 plugins from the community and core team. Ones you are likely to use most often are @fastify/cookie, @fastify/redis and @fastify/session. These are generally pretty quick to integrate and have minimal configuration. One consideration to take account of though is that Fastify and the plugins are always being improved. That means it can take a while to dust off a project you haven’t touched in a while and bring it up-to-date.
Fastify DX is in the pipeline. It brings Vite-powered front end solutions in Svelte , React and other frameworks to Fastify, and is already in alpha. This will let you create full stack apps using Fastify together with your preferred frontend.
🗳 Poll #
🌡 Mercurius #
I was using Apollo GraphQL server previously but opted for Mercurius for tighter Fastify integration. It was a GraphiQL web frontend like Apollo, which is handy for debugging your queries.
Mercurius also has its own testing integration for integration testing.
⛓ Nexus #
Nexus is kind of glue for your database and GraphQL. It plays a similar role as TypeGraphQL; helping you generate GraphQL schemas from your TypeScript models for your apps entities. You use the generates schema to initialize your GraphQL server. The way for coding up your entities is quite different, comparing TypeGraphQL to Nexus; switching involved a bit of refactoring. With TypeGraphQL, you define resolvers (functions detailing what data to respond to each GraphQL query or mutation with) as classes and decorate them with your predefined GraphQL types.
Here’s the Nexus resolver for a basic Hello
query. It just responds
with the text Hello everybody!
. Typically, though, you will take
in input from the query, process it, perhaps checking for a logged-in user and then querying your
database to form the response data.
I like how Nexus outputs a GraphQL schema file (schema.graphl
)
into your project folder and also a TypeScript file with all the types generated from your schema
(nexus-typegen.ts
in the repo). This all comes from the resolver and
entity model definitions which you provide.
It took a bit of getting used to and the Nexus tutorial was super helpful . That uses Apollo Server, Jest, and SQLite with Prisma to build out a basic GraphQL API for creating and editing blog posts. I followed along but added a few extra queries to cement my understanding and used Mercurius, uvu and PostgreSQL instead of Apollo, Jest and SQLite. The code in the repo is based on the tutorial but with this new stack and a few extra queries.
What does Prisma Bring to the Party? #
Prisma is fantastic for working with databases in your projects. You create a schema for your database (can be PostgreSQL, SQLite or others) and it generates TypeScript types for you and a set of utility functions for CRUD operations. The schema is a single file listing your database entities and their relations. The Prisma VS Code extension helps create and format it. Prisma also helps generate migration files whenever you update your database schema. I use it with Remix sites as well as API projects. Kent C Dodds is a Prisma fan too! Give it a spin on your next pet project if you haven’t yet tried it out.
uvu Testing #
uvu is a fast test runner. There’s another article on setting up uvu with Fastify so we won’t go into it in detail here. It has a much lighter footprint than Jest and sits in the same class as Vitest. You can also use uvu to unit test UI components, in Svelte for example. In the repo, we have a little helper function within a test context which spins up a new Fastify instance for testing. It then takes GraphQL queries as an input, converting them to fetch requests and injecting them into that live Fastify instance.
The repo code includes a docker-compose.yml
file with two PostgreSQL
instances, one for dev and another for testing:
Notice, we omit the volumes field on the test instance because we do not need data to persist in
the test environment. As well as this, the second instance listens on a different port (5435
), but connects to 5432
on your machine. For this to work, we have
two .env
files and set DATABASE_URL
in the test one to use port 5435
:
🙌🏽 Fastify GraphQL API Stack: Wrapping Up #
We had a look at an up-to-date Fastify GraphQL API stack and some reasoning for the choices made. In particular, we saw:
- some plugins in the Fastify ecosystem,
- what Nexus is and some differences to TypeGraphQL,
- some code snippets from the stack, like injecting GraphQL queries into a running Fastify server for unit testing.
Please have a look at the stack code if you haven’t yet. It’s in the Rodney Lab GitHub repo . I hope you find it useful for your own projects. Keen to hear your feedback on how it can be further modernized. Especially if you know new related tools, which I have not included.
🏁 Fastify GraphQL API Stack: Summary #
Is there a GraphQL server for Fastify? #
- There is a plugin for Apollo Server to make it work with Fastify. Mercurius is an alternative GraphQL server, from the Fastify team. It is performant, just like Fastify, and offers tight with Fastify, as you would expect. On top, it works well with Nexus, TypeGraphQL and Prisma, and has fine docs with integration examples. Mercurius has a GraphiQL server built in, like Apollo. This is fantastic for debugging queries.
What alternative are there to TypeGraphQL? #
- TypeGraphQL is a tool for stitching together GraphQL APIs. It helps you generate GraphQL schema from TypeScript classes describing your data model. Nexus is an alternative offering similar functionality. Both are code-first solutions — you write code, which the tool uses to create a GraphQL schema for you. That is, rather than starting out by writing the GraphQL schema. While you use decorators on TypeScript classes to spec out your data model with TypeGraphQL, Nexus uses regular TypeScript functions. For a new project, either is probably just as easy to get going on. Switching from one to the other requires some refactoring, though.
How can you set up a PostgreSQL database locally for testing? #
- You can use Docker and the docker-compose tool to create a local test database together with a dev one. In your `docker-compose.yml` file create a second database and set ports on this one for example to `'5435:5432'` so Docker will be listening on post 5435 (in this case) for PostgreSQL queries but map them to port 5432 on your machine. For the second test instance, if you do not need the test data to persist, you can omit the volumes field. You can create separate `.env.dev` and `.env.test` environment variable files, containing the URL for the required database. Then, using with the `dotenv` package, in your test setup file, include the lines `import { config } from 'dotenv';` and `config({ path: '.env.test' });`.
🙏🏽 Fastify GraphQL API Stack: Feedback #
Have you found the post useful? Would you prefer to see posts on another topic instead? Get in touch with ideas for new posts. Also, if you like my writing style, get in touch if I can write some posts for your company site on a consultancy basis. Read on to find ways to get in touch, further below. If you want to support posts similar to this one and can spare a few dollars, euros or pounds, then please consider supporting me through Buy me a Coffee.
Just dropped a new post on a GraphQL API template written in TypeScript using 🔥 Fastify as server, Mercurius, Nexus and Prisma with PostgreSQL, also uvu!
— Rodney (@askRodney) August 19, 2022
Hopefully useful if you want to combine some of these on a project.
#askRodney #api @fastifyjs https://t.co/33siG2UHmY
Finally, feel free to share the post on your social media accounts for all your followers who will find it useful. As well as leaving a comment below, you can get in touch via @askRodney on Twitter and also askRodney on Telegram . Also, see further ways to get in touch with Rodney Lab. I post regularly on Astro as well as SvelteKit. Also, subscribe to the newsletter to keep up-to-date with our latest projects.