A simple declarative-first Node.js starter project utilizing TypeScript, Fastify, and OpenAPI for scalable and reliable API development.
To set up and run the service:
-
Install dependencies:
yarn install
-
Build, lint, and test the package:
yarn all
-
Run the service:
yarn watch
-
Run the service with open-telemetry:
yarn trace
The API schema definitions for this project are located in packages/api/src/schema/**
. We use @asteasolutions/zod-to-openapi
to define and validate APIs. This approach leverages Zod schemas to not only validate but also generate OpenAPI specifications directly from the schema definitions, streamlining the process and ensuring consistency between validation logic and API documentation. A lightweight wrapper has been added to the registry
object, registerApi
which makes it clean and simple to register an api.
// Register endpoints by calling registerApi
registry.registerApi({
tags: ["todos"],
name: "createTodo",
description: "Create a new to-do item",
method: "post",
path: "/todos",
request: CreateTodoRequestSchema,
response: {
statusCode: 201,
schema: TodoItemSchema,
},
roles: ["write"],
});
- Define your API models and request/response objects using Zod in
packages/api/src/schema
. - Use
@asteasolutions/zod-to-openapi
to register the endpoint. - The generated OpenAPI spec can then be used for routing, validation, and client SDK generation.
This repository follows a monorepo setup managed by Yarn Workspaces and Turbo Repo. Below is an overview of the core folders:
- Contains Docker configurations, specifically for Jaeger, an open-source tool for distributed tracing.
- All project modules and packages reside here:
api
: Defines the OpenAPI schema and handles API-related logic, using Fastify as the HTTP server.client-grpc
: A generated gRPC client SDK generated byts-proto
.client-sdk
: A generated SDK for clients based on the OpenAPI spec, created with tools likeorval
.service
: Contains business logic and integrates with other packages.
The repository provides several root-level scripts to manage and automate common tasks:
all
: Runs build, format, lint, and test tasks sequentially.preinstall
: Ensures Yarn is used instead of npm to prevent potential dependency issues.build
: Builds all packages using Turbo Repo.lint
: Runs linting on all packages.format
: Formats code using Prettier.test
: Runs tests across all packages.watch
: Watches for changes in theservice
package.trace
: Starts Jaeger and runs tracing on theservice
package.jaeger:start
andjaeger:stop
: Controls the Jaeger Docker instance for distributed tracing.for-each
: Executes tasks for each workspace sequentially, useful for complex workflows that require running one task at a time.
- Node.js: Version 22, enabling recent features and optimizations.
- Yarn: Used for package management and workspace orchestration.
- Turbo Repo: Speeds up builds and test processes for the monorepo.
- TypeScript: For static typing and strict validation.
- Prettier: Code formatting to enforce a consistent style.
- ESLint: Linting for code quality assurance.
- Gnostic: Tools to transform OpenAPI specs into Protocol Buffers definitions.
- protoc: For compiling
.proto
files into gRPC services. - ts-proto: A TypeScript code generator for Protocol Buffers.
This setup offers a highly structured environment for consistent, scalable, and maintainable code. By using Turbo Repo for task orchestration, zod-to-openapi
for schema and API definition, and Fastify with fastify-openapi-glue
, this project is designed to be efficient and developer-friendly.
-
Fastify: A fast and low overhead web framework for Node.js.
- @fastify/cors: Cross-Origin Resource Sharing (CORS) for Fastify.
- @fastify/helmet: Helmet integration for Fastify to add security headers.
- @fastify/jwt: JSON Web Token (JWT) authentication for Fastify.
- @fastify/rate-limit: Rate limiting for Fastify.
- @fastify/response-validation: Response validation for Fastify.
- @fastify/swagger: Swagger documentation for Fastify.
- @fastify/swagger-ui: Swagger UI for interactive API documentation.
-
@grpc/grpc-js: gRPC server runtime.
- @grpc/proto-loader: Loads
.proto
files directly for use with gRPC.
- @grpc/proto-loader: Loads
-
ajv: JSON Schema Validator.
- ajv-errors: Custom error messages for Ajv.
-
Pino: High-performance logging library for Node.js.
- pino-pretty: Formatter for pretty-printing Pino logs.
-
Zod: TypeScript-first schema declaration and validation library.
- @asteasolutions/zod-to-openapi: Converts Zod schemas to OpenAPI definitions.
- Orval: Generates client SDKs from OpenAPI specs.
- json-schema-faker: Generates fake data based on JSON Schema definitions.
- Gnostic & Gnostic-GRPC: Tools to transform OpenAPI specs into Protocol Buffers definitions.
- Protobuf Compiler (
protoc
): For compiling.proto
files into gRPC services. - ts-proto: A TypeScript code generator for Protocol Buffers, used to generate TypeScript types from
.proto
files. This package allows seamless integration of gRPC types into TypeScript projects.
- OpenTelemetry: Provides distributed tracing and metrics collection.
- @opentelemetry/instrumentation-fastify: Fastify instrumentation for OpenTelemetry.
- @opentelemetry/sdk-trace-node: Node.js trace SDK for OpenTelemetry.
- @opentelemetry/exporter-metrics-otlp-proto: OpenTelemetry Protocol (OTLP) exporter for metrics.
- TypeScript: Strongly typed programming language that builds on JavaScript.
- ESLint: Pluggable JavaScript linter.
- @typescript-eslint/eslint-plugin: ESLint plugin for TypeScript support.
- eslint-plugin-import: Linter for ES6+ import/export syntax.
- eslint-plugin-prettier: Integrates Prettier formatting rules into ESLint.
- Prettier: Code formatter to enforce consistent style.
- Vitest: A fast unit test framework powered by Vite.
These are used for open-telemetry reporting in development/local environments.
- Jaeger: Distributed tracing system for microservices.
- Zipkin: Distributed tracing system compatible with Jaeger.
- Prometheus: Monitoring system and time-series database.