NestJS 모듈과의 싸움을 그만두세요: Rikta를 만나보세요
I’m happy to translate the article for you, but I need the actual text of the post. Could you please paste the content you’d like translated (excluding any code blocks or URLs you want to keep unchanged)? Once I have the text, I’ll provide the Korean translation while preserving the original formatting and source link.
Source:
모듈 문제
NestJS 모듈은 실제 문제, 즉 의존성 경계를 해결합니다. 대규모 코드베이스에서 혼란을 방지하지만, 그 대가가 있습니다.
새로운 서비스를 추가할 때마다 다음을 해야 합니다:
@Injectable()로 서비스를 생성합니다.- 모듈의
providers배열에 추가합니다. - 다른 모듈에서 필요하면
exports배열에 추가합니다. - 사용되는 모든 곳에서 해당 모듈을 임포트합니다.
전형적인 NestJS 모듈은 다음과 같습니다:
// user.module.ts
@Module({
imports: [
DatabaseModule,
ConfigModule,
AuthModule,
LoggingModule,
],
controllers: [UserController],
providers: [
UserService,
UserRepository,
UserValidator,
UserMapper,
],
exports: [UserService, UserRepository],
})
export class UserModule {}
이것은 많은 보일러플레이트—빠르게 늘어나는 순수 설정 오버헤드입니다.
중간 규모의 애플리케이션은 20개 이상의 모듈을 가질 수 있으며, 각 모듈마다 5‑10개의 프로바이더가 있습니다. 비즈니스 로직을 작성하기보다 배열을 관리하는 데 더 많은 시간을 소비하게 됩니다.
가장 안 좋은 점은? 배열 중 하나에 오타가 생기면 전체 의존성 그래프가 깨지고, 디버깅에 몇 시간이 걸릴 수 있습니다.
모듈이 필요 없다고 가정한다면?
Rikta은 Fastify 위에 구축된 새로운 TypeScript 프레임워크입니다. NestJS의 장점(데코레이터, DI, 구조)을 유지하면서 모듈 설정을 완전히 제거합니다.
imports배열 없음.exports배열 없음.providers배열 없음.
클래스에 데코레이터만 붙이면 모든 것이 동작합니다.
// user.service.ts
import { Injectable } from '@riktajs/core';
@Injectable()
export class UserService {
getUsers() {
return ['Alice', 'Bob'];
}
}
// user.controller.ts
import { Controller, Get, Autowired } from '@riktajs/core';
import { UserService } from './user.service';
@Controller('/users')
export class UserController {
@Autowired()
private userService!: UserService;
@Get()
getUsers() {
return this.userService.getUsers();
}
}
그게 전부입니다—모듈 파일도 없고, 등록도 필요 없습니다. Rikta는 시작 시 코드를 스캔하고 의존성을 자동으로 해결합니다.
How Zero‑Config Autowiring Works
Rikta는 세 가지 메커니즘을 사용합니다:
- Automatic Discovery – 시작 시
@Controller()또는@Injectable()으로 데코레이트된 클래스를 프로젝트 전체에서 스캔합니다. 생성자 파라미터와@Autowired()데코레이터를 기반으로 의존성 그래프를 구축합니다. - Global Provider Registry – 모든 프로바이더는 하나의 레지스트리에 저장됩니다. 주입 가능한 클래스는 앱 어디서든 사용할 수 있으며, 별도의 export나 import가 필요하지 않습니다.
- Dependency Resolution – Rikta는 TypeScript 메타데이터(
reflect-metadata사용)를 읽어 각 클래스가 무엇을 필요로 하는지 파악하고, 올바른 순서대로 인스턴스를 생성해 자동으로 주입합니다.
초기화 과정에서 순환 의존성이 감지되면 명확한 오류가 발생합니다:
Error: Circular dependency detected:
UserService -> AuthService -> UserService
암호 같은 스택 트레이스도 없고, 런타임에서 깜짝 놀랄 일도 없습니다.
나란히 비교
NestJS에서 새로운 기능 만들기
// 1. Create the service
@Injectable()
export class PaymentService {
constructor(private configService: ConfigService) {}
}
// 2. Create the module
@Module({
imports: [ConfigModule],
providers: [PaymentService],
exports: [PaymentService],
})
export class PaymentModule {}
// 3. Import in app.module.ts
@Module({
imports: [PaymentModule, /* ... */],
})
export class AppModule {}
// 4. Import in any module that needs it
@Module({
imports: [PaymentModule],
providers: [OrderService],
})
export class OrderModule {}
Rikta에서 동일한 기능 만들기
@Injectable()
export class PaymentService {
@Autowired()
private configService!: ConfigService;
}
완료.
성능 이점
Rikta는 HTTP 레이어로 Fastify를 사용합니다. Fastify는 벤치마크에서 초당 30,000 요청을 처리합니다.
공식 벤치마크 결과:
| 측정 항목 | Rikta vs. NestJS |
|---|---|
| 시작 시간 | 43 % 더 빠름 |
| GET 요청 | 41 % 더 빠름 |
| POST 요청 | 25 % 더 빠름 |
| 라우트 매개변수 | 46 % 더 빠름 |
Rikta는 기본 Fastify에 비해 **2‑5 %**의 오버헤드만 추가하여 DI와 데코레이터를 제공하면서 속도를 희생하지 않습니다.
Built‑in Zod Validation
NestJS는 class-validator 데코레이터에 의존하므로 타입을 두 번 정의해야 합니다: 한 번은 TypeScript용, 한 번은 검증용.
Rikta는 Zod를 기본적으로 통합합니다. 스키마를 한 번 정의하면 검증과 TypeScript 타입을 자동으로 얻을 수 있습니다.
import { Controller, Post, Body, z } from '@riktajs/core';
const CreateUserSchema = z.object({
email: z.string().email(),
name: z.string().min(2),
age: z.number().optional(),
});
@Controller('/users')
export class UserController {
@Post()
create(@Body(CreateUserSchema) user: z.infer) {
// 'user' is validated AND typed
// Invalid requests return 400 automatically
return { created: user };
}
}
중복된 타입 정의가 없으며, 검증 실패에 대한 수동 오류 처리도 필요 없습니다.
Rikta를 언제 사용할까
Rikta가 가장 잘 맞는 경우:
- 스타트업 및 MVP(Minimum Viable Product)에서 개발 속도가 중요한 경우.
- 소규모~중간 규모 팀(1‑15명 개발자)으로, 깔끔하고 설정이 필요 없는 DI 시스템을 원하는 경우.
NestJS의 사용 편의성을 좋아하지만 모듈 보일러플레이트가 지겹다면 Rikta를 시도해 보세요.
- 마이크로서비스 – 각 서비스가 독립적으로 집중될 수 있는 경우.
- NestJS를 알고 있는 개발자로, 보일러플레이트를 줄이고 싶은 경우.
NestJS를 고려해야 할 상황:
- 팀 규모가 크고, 엄격한 모듈 경계가 필요한 경우.
- 방대한 NestJS 생태계(특정 어댑터, 플러그인 등)가 필요할 때.
- 조직에서 명시적인 의존성 문서를 요구할 때.
Getting Started
Create a new project in seconds:
npx @riktajs/cli new my-app
cd my-app
npm run dev
Your API runs at http://localhost:3000.
The CLI generates a complete project with:
- TypeScript configuration optimized for Rikta
- Example controller with REST endpoints
- Example service with dependency injection
- Hot‑reload development server
리소스
- 문서:
- GitHub:
- NPM:
Rikta는 MIT 라이선스를 가지고 있으며 오픈 소스입니다.
제로‑컨피그 프레임워크를 사용해 보셨나요? 모듈과 자동와이어링의 트레이드오프에 대해 어떻게 생각하시나요? 댓글에 경험을 공유해 주세요.