Archive
43
practical posts on NestJS, testing, architecture, and backend delivery.

NestJS Ninja
Backend lessons & architecture notes
TypeScript servers
Practical writing on modules, providers, queues, testing, microservices, and the decisions that keep backend codebases easy to change.
@Module({
imports: [
ConfigModule.forRoot(),
QueueModule,
ObservabilityModule,
],
controllers: [ArticlesController],
providers: [ArticlesService],
})
export class AppModule {}Archive
43
practical posts on NestJS, testing, architecture, and backend delivery.
Coverage
4
years of notes, experiments, and backend implementation write-ups.
Topics
Featured

One GraphQL schema, many NestJS services. We take a code-first GraphQL API and split it into Apollo Federation v2 subgraphs — a users service that owns the User entity, an orders service that extends it — composed by a gateway that plans queries across both without the client ever knowing.
Latest
Pipes are the front door of a NestJS request — they transform and validate input before it ever reaches a service. This post covers the ValidationPipe and DTOs, the options that actually matter (whitelist, transform), parsing and custom pipes, a Zod alternative, generating Swagger/OpenAPI docs from the same DTOs, and how to make validation failures come back in the same error shape as the rest of your API.
Most NestJS apps throw a mix of HttpException, raw Error, and string messages — so the client gets a different shape every time. This post builds a layered error model instead: a base domain error with stable, namespaced string codes, per-domain exception families with typed constructors, cause-chaining, and a single global filter that renders any of them into one consistent, leak-free response (with an RFC 9457 variant).
Unit tests mock the repository. Integration and e2e tests hit a real database — and that is where you need realistic seed data. The TypeORM ecosystem has no great answer for this, and the libraries that exist break every time TypeORM changes its internals. This post builds a tiny factory library that inverts the dependency: TypeORM becomes a six-line adapter, so upgrading it can never break your seeds.
The constructor is not where initialization belongs. NestJS gives you five lifecycle hooks — OnModuleInit, OnApplicationBootstrap, OnModuleDestroy, BeforeApplicationShutdown, and OnApplicationShutdown — each firing at a precise moment in the application's life. This post shows you what each one is for, the order they run in, and what graceful shutdown actually looks like in production.
Most NestJS services are singletons — and that is fine until you need per-request isolation for tenant context, correlation IDs, or stateful helpers. This post explains all three scopes, scope bubbling, durable providers, and when each one belongs in your application.