Backend Development 10 min read

Introducing NestJS and Nesk: Backend Framework Overview and Koa Integration

This article explains the core concepts of NestJS—including modules, controllers, providers, guards, interceptors, and validation pipes—provides practical code examples, and describes how the Nesk fork adapts Nest's architecture to a Koa‑based environment for seamless integration with existing internal frameworks.

Hujiang Technology
Hujiang Technology
Hujiang Technology
Introducing NestJS and Nesk: Backend Framework Overview and Koa Integration

This article introduces the NestJS framework, whose design is inspired by Angular and Java Spring, and explains its purpose as a modular, testable, and scalable backend architecture for Node.js applications.

It presents a minimal bootstrap example that creates a Nest application, applies a global ValidationPipe , and starts listening on port 3000:

async function bootstrap() {
  const app = await NestFactory.create(ApplicationModule);
  app.useGlobalPipes(new ValidationPipe());
  await app.listen(3000);
}
bootstrap();

The ApplicationModule is defined with the @Module decorator, importing other modules and configuring middleware:

@Module({
  imports: [CatsModule],
})
export class ApplicationModule implements NestModule {
  configure(consumer: MiddlewaresConsumer): void {
    consumer.apply(LoggerMiddleware).with('ApplicationModule').forRoutes(CatsController);
  }
}

A CatsModule groups related controllers and services, while the CatsController demonstrates routing, guards, interceptors, and DTO validation using decorators such as @Controller('cats') , @Get , @Post , @UseGuards(RolesGuard) , and @UseInterceptors(LoggingInterceptor, TransformInterceptor) :

@Controller('cats')
@UseGuards(RolesGuard)
@UseInterceptors(LoggingInterceptor, TransformInterceptor)
export class CatsController {
  constructor(private readonly catsService: CatsService) {}

  @Post()
  @Roles('admin')
  async create(@Body() createCatDto: CreateCatDto) {
    return this.catsService.create(createCatDto);
  }

  @Get()
  async findAll(): Promise
{
    return this.catsService.findAll();
  }

  @Get(':id')
  async findOne(@Param('id', new ParseIntPipe()) id: number): Promise
{
    return this.catsService.findOne(id);
  }
}

The article provides a custom RolesGuard implementation that uses the Reflector to retrieve required roles from metadata and decides access based on a simple boolean check:

export class RolesGuard implements CanActivate {
  constructor(private readonly reflector: Reflector) {}

  canActivate(request, context: ExecutionContext): boolean {
    const { handler } = context;
    const roles = this.reflector.get
('roles', handler);
    if (!roles) {
      return true;
    }
    // custom role validation logic here
    return true;
  }
}

A LoggingInterceptor example shows how to log execution time using RxJS operators:

export class LoggingInterceptor implements NestInterceptor {
  intercept(dataOrRequest, context: ExecutionContext, stream$: Observable
): Observable
{
    console.log('Before...');
    const now = Date.now();
    return stream$.do(() => console.log(`After... ${Date.now() - now}ms`));
  }
}

The ValidationPipe works together with a DTO class that uses class‑validator decorators to enforce input shape:

export class CreateCatDto {
  @IsString()
  readonly name: string;

  @IsInt()
  readonly age: number;

  @IsString()
  readonly breed: string;
}

Because the author's organization already uses a Koa‑based framework (Aconite), the article introduces Nesk , a fork of Nest that replaces the Express core with a Koa adapter. The required adapter code creates a NeskAconite instance, passes project configuration and middlewares, and then bootstraps the application:

import { NeskFactory } from '@neskjs/core';
import { NeskAconite } from '@hujiang/nesk-aconite';
import { ApplicationModule } from './app.module';
import { config } from './common/config';
import { middwares } from './common/middlware';

async function bootstrap() {
  const server = new NeskAconite({
    projectRoot: __dirname,
    middlewares,
    config,
  });
  const app = await NeskFactory.create(ApplicationModule, server);
  await app.listen(config.port);
}
bootstrap();

The author notes that Nest’s current dependency injection uses a reflective injector, whereas Angular’s newer static injector offers better performance, and suggests that a future version of Nesk could adopt such improvements. They also discuss the possibility of supporting multiple underlying HTTP servers (Express, Koa) via an adapter layer and invite community contributions.

backend developmentNode.jsdependency injectionKoaNestJSInterceptorsGuards
Hujiang Technology
Written by

Hujiang Technology

We focus on the real-world challenges developers face, delivering authentic, practical content and a direct platform for technical networking among developers.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.