logoGERASOFT
Blog

From Idea to App - How to set up a Fastify server

Reading time: 4-15 minsTechnicality: 4/5Last updated: Feb 10, 2025
From Idea to App - How to set up a Fastify backend

Now that the front end prototype is ready for the product team to conduct user testing on, we will work on replacing our fake API. With this update we will set the foundation to be able to move task data out of the local browser scope to the cloud, and implement authentication.

Stack

  • Fastify: A high‑performance, Node.js‑based web framework that delivers speed and a vast ecosystem of plugins like security, compression, and rate limiting.
  • GraphQL with Apollo Server: Our GraphQL API is built with Apollo Server integrated into Fastify (via the @as‑integrations/fastify adapter). This setup provides us with a robust schema, great developer experience and seamless client integration with Apollo Client.
  • Zod: We use Zod on both front and back ends for schema validation—ensuring consistency in validating form data as well as environment configuration.
  • MongoDB with Mongoose: For database we have chosen MongoDB and Mongoose for efficient schema definition and data modelling.

Upcoming

Our goal for this project is to set up a minimalistic working state of the fastify server, GraphQL API, and make a connection to the database.

We split it into 3 parts:

  • Set up Fastify server with a working /health endpoint
  • Set up a MongoDB connection, and create a temporary counter model to test out the connection
  • Set up a GraphQL API endpoint with a Health query

Create Fastify App

ClickUp ticket

Project Setup & Dependencies

  • Created a new app in apps/api and set up core dependencies, including Fastify, Apollo Server, Zod, and essential Fastify plugins for security, compression, and rate limiting.
  • Configured tsup for bundling and running the development server.

Configuration & Environment Management

  • Introduced a .env.sample file defining essential environment variables such as NODE_ENV, PORT, and CORS_ALLOWLIST, ensuring clearer configuration management.
  • Implemented a config module using Zod schemas to validate environment variables and provide default values.

Server & Plugin Architecture

  • server.ts initialises a structured Fastify instance with key middleware, including CORS, Helmet for security, and Swagger for API documentation.
  • The config plugin integrates environment configurations directly into Fastify, making them easily accessible.

Routes & API Documentation

  • Added a /health route with schema validation for a simple API health check.
  • Implemented OpenAPI definitions for API documentation, accessible at /documentation.

Testing Infrastructure

  • Set up vitest with a test utility for running a Fastify test server.
  • Created a unit test for the /health route to verify the API responds with { ok: true }.

Configs

  • Added a server specific eslint-config at packages/eslint-config/server.js
  • Added a NodeJS specific tsup-config at packages/tsup-config/src/node.ts
  • Added a NodeJS specific typescript config at packages/typescript-config/node.json

GitHub changes

Set up MongoDB with Mongoose

ClickUp ticket

New @repo/mongodb-helpers Package

For MongoDB-related operations a reusable package @repo/mongodb-helpers was created to contain:

  • Schemas: Centralised Mongoose schemas, including CounterSchema, to standardise data models.
  • Base Document Fields: Shared schema fields such as _id, createdAt, and updatedAt for consistency across documents.
  • Database Connection Helper: A utility function to establish and maintain MongoDB connections efficiently.
  • Event Time Handling: A function to ensure timestamps (createdAt, updatedAt) are properly set on document updates.

This package is now included as a workspace dependency and integrated within the API.

MongoDB Integration in the API

  • Introduced a DB_CONNECTION_STRING environment variable to facilitate database connection management.
  • Ensured environment validation via the existing config module.

A new Fastify plugin, counterPlugin, was implemented to monitor API connection counts. This plugin:

  • Utilises a MongoDB-backed counter model via Mongoose.
  • Implements an increaseCounter function that:
    • Tracks API connections.
    • Logs connection count and last connection timestamp on server startup (temporary logging).
  • Registers counterPlugin in plugins/index.ts alongside existing plugins.
  • Extends Fastify's type definitions to include the increaseCounter method for seamless access.

GitHub changes

Create GraphQL API

ClickUp ticket

New @repo/graphql Package

A new workspace package, @repo/graphql, was introduced to centralise GraphQL-related utilities across projects. It includes:

  • Schemas: Common GraphQL type definitions (common.ts, health.ts).
  • Queries: Query definitions for use in frontend clients.
  • TypeScript Codegen: Configured graphql-codegen to generate TypeScript types and operations.

GraphQL Integration in API

  • GraphQL Type Generation:
    • Added graphql-codegen for automatic type generation based on GraphQL schemas in codegen.ts to generate TypeScript types for resolvers.
  • Apollo Server Setup:
    • Integrated Apollo Server with Fastify via @as-integrations/fastify.
    • Defined a contextFunction for injecting context to the GraphQL resolvers.
    • Implemented executableSchema.ts using @graphql-tools/schema and @graphql-tools/merge – combining the schemas from @repo/graphql and the resolvers.
  • Resolvers:
    • Added healthResolvers to provide a basic health check query.
    • Created a commonResolvers module with custom scalar types for BigInt and RegExp.
  • GraphQL Route:
    • Registered /graphql endpoint in Fastify via graphqlRoutes.
    • Extended Fastify’s routing system to include GraphQL alongside REST routes.

API Error Handling Enhancements

  • Introduced GeneralError class for handling GraphQL errors with structured messages.
  • Utilises @repo/translation/en/errors.json to maintain error messages in a centralised translation system.

GitHub changes

Conclusion

With this release, we have:

  • A production‑ready Fastify server.
  • Seamless MongoDB connectivity via Mongoose.
  • A fully operational GraphQL endpoint with autogenerated TypeScript types.
  • Robust testing and configuration management in place.

GitHub links

Next steps

We will continue to build our API, and implement user management:

  • implement auth-service
  • authentication GraphQL endpoints (sign in, sign out, sign up)
  • session management with JSON web tokens (JWTs)
  • User and Organization database models

Here's how our timeline look like now:

12345
User management backend implementation
5 d