๐Ÿ’ก 01. NestJS ์†Œ๊ฐœ โ€” ์™œ ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ํ•„์š”ํ•œ๊ฐ€?

2026๋…„ 2์›” 26์ผ ์ˆ˜์ •๋จ

๐Ÿ“‹ ๊ฐœ์š”

NestJS์˜ ๊ธฐ๋ณธ ๊ฐœ๋…๊ณผ ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ๋ฅผ ์ดํ•ดํ•˜๊ณ , ํ•ต์‹ฌ ๊ฐœ๋…์ธ ๋ชจ๋“ˆ, ์ปจํŠธ๋กค๋Ÿฌ, ์„œ๋น„์Šค, ์˜์กด์„ฑ ์ฃผ์ž…์„ ๋ฐฐ์›๋‹ˆ๋‹ค.

๐Ÿ“‹ ๋ชฉ์ฐจ


๐Ÿ“Œ ์ด ๋ฌธ์„œ๋ฅผ ์ฝ๊ธฐ ์ „์—

โฑ๏ธ ์˜ˆ์ƒ ์ฝ๊ธฐ ์‹œ๊ฐ„: 15๋ถ„ (์ „์ฒด) / ํ•ต์‹ฌ ํŒŒํŠธ๋งŒ: 7๋ถ„

๐Ÿงณ ์ „์ œ ์ง€์‹ ์ฒดํฌ๋ฆฌ์ŠคํŠธ
์•„๋ž˜ ํ•ญ๋ชฉ์„ ๋ชจ๋‘ ์•Œ๋ฉด ๋ฐ”๋กœ [4๋Œ€ ํ•ต์‹ฌ ๊ฐœ๋…]๋ถ€ํ„ฐ ์ฝ์–ด๋„ ๋ผ:

  • JavaScript๋‚˜ TypeScript์˜ ๊ธฐ๋ณธ ๋ฌธ๋ฒ•์„ ์ฝ์„ ์ค„ ์•ˆ๋‹ค.
  • REST API๊ฐ€ ๋ฌด์—‡์ธ์ง€ ๋Œ€๋žต์ ์œผ๋กœ ์•ˆ๋‹ค (GET, POST ๋“ฑ).
  • Express.js ๊ฐ™์€ ๋ฐฑ์—”๋“œ๋ฅผ ์•„์ฃผ ์กฐ๊ธˆ์ด๋ผ๋„ ๋งŒ์ ธ๋ณธ ์ ์ด ์žˆ๋‹ค.
  • ํ„ฐ๋ฏธ๋„์—์„œ npm install์ด๋‚˜ npx ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.

๐Ÿ—บ๏ธ ์ด ๋ฌธ์„œ์˜ ํ๋ฆ„
NestJS์˜ ํƒ„์ƒ ๋ฐฐ๊ฒฝ โ†’ 4๊ฐ€์ง€ ํ•ต์‹ฌ ๊ตฌ์กฐ(์ปจํŠธ๋กค๋Ÿฌ/์„œ๋น„์Šค/๋ชจ๋“ˆ/DI) โ†’ ์ฒซ ์•ฑ ๋„์šฐ๊ธฐ โ†’ ์ž์ฃผ ๊ฒช๋Š” ์—๋Ÿฌ โ†’ ์น˜ํŠธ์‹œํŠธ

๐ŸŽฏ ์ด ๋ฌธ์„œ๋ฅผ ๋‹ค ์ฝ์œผ๋ฉด ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ

  • NestJS๊ฐ€ ์™œ Express๋ณด๋‹ค ๋Œ€๊ทœ๋ชจ ํ”„๋กœ์ ํŠธ์— ์ข‹์€์ง€ ์„ค๋ช…ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ์›น ์š”์ฒญ์ด ๋“ค์–ด์™”์„ ๋•Œ ์ปจํŠธ๋กค๋Ÿฌ์™€ ์„œ๋น„์Šค๊ฐ€ ์–ด๋–ป๊ฒŒ ์ผ์„ ๋‚˜๋ˆ„๋Š”์ง€ ์„ค๋ช…ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ๋‚˜๋งŒ์˜ ์ฒซ ๋ฒˆ์งธ NestJS ์„œ๋ฒ„๋ฅผ ๋กœ์ปฌ์— ๋„์šธ ์ˆ˜ ์žˆ๋‹ค.

๐Ÿค” ์™œ ์•Œ์•„์•ผ ํ•˜๋Š”๊ฐ€ (Express vs NestJS)

Node.js ์„ธ์ƒ์—์„œ ๊ฐ€์žฅ ์œ ๋ช…ํ•œ ๋ฐฑ์—”๋“œ ๋„๊ตฌ๋Š” ์˜์‹ฌ์˜ ์—ฌ์ง€ ์—†์ด Express.js ์•ผ.
ํ•˜์ง€๋งŒ Express๋Š” ๋„ˆ๋ฌด๋‚˜๋„ ์ž์œ ๋กœ์›Œ. ์–ด๋””์— ๋ผ์šฐํ„ฐ๋ฅผ ๋‘๊ณ , ์–ด๋””์— ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ฝ”๋“œ๋ฅผ ์“ธ์ง€ ์•„๋ฌด๋Ÿฐ ๊ทœ์น™์„ ๊ฐ•์ œํ•˜์ง€ ์•Š์•„.

๐Ÿค” ์ž ๊น, ๋จผ์ € ์ƒ๊ฐํ•ด๋ด
5๋ช…์ด ํ•จ๊ป˜ Express๋กœ ์„œ๋ฒ„๋ฅผ ๋งŒ๋“ ๋‹ค๊ณ  ์น˜์ž. ๊ฐ์ž ์ž๊ธฐ ๋งˆ์Œ๋Œ€๋กœ ํด๋”๋ฅผ ๋งŒ๋“ค๊ณ  ์ฝ”๋“œ๋ฅผ ์งœ๋ฉด, ๋‚˜์ค‘์— ์ฝ”๋“œ๊ฐ€ ์–ด๋–ป๊ฒŒ ๋ ๊นŒ?

Express์˜ ์ž์œ ๋กœ์›€์€ ํ˜ผ์ž ๋งŒ๋“ค ๋•Œ๋Š” ์ถ•๋ณต์ด์ง€๋งŒ, ์—ฌ๋Ÿฌ ๋ช…์ด ํ•จ๊ป˜ ์ผํ•˜๋Š” ์‹ค๋ฌด์—์„œ๋Š” ์—„์ฒญ๋‚œ ํ˜ผ๋ž€(์ŠคํŒŒ๊ฒŒํ‹ฐ ์ฝ”๋“œ)์„ ๋‚ณ์•„. ์–ด๋””์— ๋ญ๊ฐ€ ์žˆ๋Š”์ง€ ์ฐพ์„ ์ˆ˜๊ฐ€ ์—†๊ฒŒ ๋˜๊ฑฐ๋“ .

NestJS ๋Š” ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ๋“ฑ์žฅํ–ˆ์–ด. Angular ์•„ํ‚คํ…์ฒ˜์—์„œ ์˜๊ฐ์„ ๋ฐ›์•„ "์ฝ”๋“œ๋Š” ๋ฌด์กฐ๊ฑด ์ด๋ ‡๊ฒŒ ์งœ์•ผ ํ•ด!" ๋ผ๋Š” ๊ฐ•๋ ฅํ•˜๊ณ  ๋ช…ํ™•ํ•œ ๋ผˆ๋Œ€(Architecture)๋ฅผ ๊ฐ•์ œํ•˜๋Š” ํ”„๋ ˆ์ž„์›Œํฌ์•ผ.

ํŠน์„ฑExpressNestJS
์ž์œ ๋„100% (๊ทœ์น™ ์—†์Œ)๋‚ฎ์Œ (** ์—„๊ฒฉํ•œ ๋ผˆ๋Œ€ ๊ฐ•์ œ**)
์–ธ์–ดJavaScript ์šฐ์„ TypeScript ์™„๋ฒฝ ์ง€์›
์ ํ•ฉ๋„์ž‘๊ณ  ๋น ๋ฅธ ์‚ฌ์ด๋“œ ํ”„๋กœ์ ํŠธ์—ฌ๋Ÿฌ ๋ช…์ด ๊ฐœ๋ฐœํ•˜๋Š” ๋Œ€๊ทœ๋ชจ ์•ฑ

๐Ÿ—๏ธ ๋น„์œ ๋กœ ๋จผ์ € ์ดํ•ดํ•˜๊ธฐ

๐Ÿง’ 5์‚ด์—๊ฒŒ ์„ค๋ช…ํ•œ๋‹ค๋ฉด?

Express๊ฐ€ '๋นˆ ๋„ํ™”์ง€์™€ ํฌ๋ ˆํŒŒ์Šค'๋ผ๋ฉด, NestJS๋Š” '์กฐ๋ฆฝ ์„ค๋ช…์„œ๊ฐ€ ์žˆ๋Š” ๋ ˆ๊ณ  ๋ธ”๋ก' ์ด์•ผ.
๋„ํ™”์ง€์—๋Š” ์•„๋ฌด๋ ‡๊ฒŒ๋‚˜ ๊ทธ๋ฆด ์ˆ˜ ์žˆ์–ด์„œ ํŽธํ•˜์ง€๋งŒ, ์ปค๋‹ค๋ž€ ๋„์‹œ๋ฅผ ๊ทธ๋ฆด ๋• ๋ณต์žกํ•ด์ ธ.
๋ ˆ๊ณ ๋Š” ์ •ํ•ด์ง„ ๋ชจ์–‘๋Œ€๋กœ ๋”ฑ๋”ฑ ๋ผ์›Œ ๋งž์ถฐ์•ผ ํ•ด์„œ ์ฒ˜์Œ์—” ๊ท€์ฐฎ์ง€๋งŒ, ์นœ๊ตฌ๋“ค๊ณผ ํž˜์„ ํ•ฉ์ณ์„œ ์—„์ฒญ๋‚˜๊ฒŒ ๊ฑฐ๋Œ€ํ•œ ์„ฑ์„ ๋งŒ๋“ค์–ด๋„ ํŠผํŠผํ•˜๊ฒŒ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ์–ด!


๐Ÿงฉ 4๋Œ€ ํ•ต์‹ฌ ๊ฐœ๋… ์ดํ•ดํ•˜๊ธฐ ๐ŸŸข

๐ŸŽฏ ์ด ์„น์…˜์„ ์ฝ๊ณ  ๋‚˜๋ฉด:

  • HTTP ์š”์ฒญ์„ ๋ฐ›๋Š” ์—ญํ• (Controller)๊ณผ ์‹ค์ œ ๋กœ์ง(Service)์„ ์™„๋ฒฝํžˆ ๊ตฌ๋ถ„ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • DI๋ผ๋Š” ๋ฌด์‹œ๋ฌด์‹œํ•œ ๋‹จ์–ด์˜ ์ง„์งœ ์˜๋ฏธ๋ฅผ ์„ค๋ช…ํ•  ์ˆ˜ ์žˆ๋‹ค.

๋งˆ์น˜ ์ฒด๊ณ„์ ์œผ๋กœ ๋Œ์•„๊ฐ€๋Š” ๊ณ ๊ธ‰ ๋ ˆ์Šคํ† ๋ž‘์ฒ˜๋Ÿผ, NestJS๋Š” ์—ญํ• ์„ ์™„๋ฒฝํ•˜๊ฒŒ ๋‚˜๋ˆˆ ์„ธ ๊ฐ€์ง€ ์ฃผ์š” ์š”์†Œ๋ฅผ ๊ฐ€์ ธ.

1. ์ปจํŠธ๋กค๋Ÿฌ (Controller) โ€” ์ฃผ๋ฌธ์„ ๋ฐ›๋Š” ์›จ์ดํ„ฐ ๐Ÿ’โ€โ™‚๏ธ

์ปจํŠธ๋กค๋Ÿฌ๋Š” ์˜ค์ง "ํด๋ผ์ด์–ธํŠธ(์†๋‹˜)์˜ ์š”์ฒญ์„ ๋ฐ›๊ณ , ์„œ๋น„์Šค(์ฃผ๋ฐฉ)๋กœ ์ „๋‹ฌํ•œ ๋’ค, ๊ฒฐ๊ณผ๋ฌผ์„ ๋‹ค์‹œ ์‘๋‹ตํ•˜๋Š” ์ผ" ๋งŒ ํ•ด.

import { Controller, Get } from '@nestjs/common';
import { UsersService } from './users.service';
 
@Controller('users')  // '/users' ๊ฒฝ๋กœ์˜ ์š”์ฒญ์„ ๋‹ค ๋ฐ›์Œ
export class UsersController {
  // ์ƒ์„ฑ์ž๋ฅผ ํ†ตํ•ด ์„œ๋น„์Šค(์ฃผ๋ฐฉ์žฅ)๋ฅผ ๋ถˆ๋Ÿฌ์˜ด
  constructor(private readonly usersService: UsersService) {}
 
  @Get()              // GET ์š”์ฒญ์ด ์˜ค๋ฉด
  findAll() {
    // ์š”๋ฆฌ๋Š” ์„œ๋น„์Šค๊ฐ€ ํ•˜๊ณ , ๊ฒฐ๊ณผ๋งŒ ๋ฐ›์•„์„œ ์„œ๋น™ํ•จ!
    return this.usersService.findAllUsers();
  }
}

โŒ ๋‚˜์œ ์˜ˆ: ์ปจํŠธ๋กค๋Ÿฌ ์•ˆ์—์„œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ง์ ‘ ์ ‘์†ํ•ด์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฝ‘๋Š” ๊ฒƒ (์›จ์ดํ„ฐ๊ฐ€ ์ฃผ๋ฐฉ ๋ถˆํŒ์— ๊ณ ๊ธฐ๋ฅผ ๊ตฝ๋Š” ๊ฒฉ)

2. ์„œ๋น„์Šค (Service) โ€” ์š”๋ฆฌ๋ฅผ ํ•˜๋Š” ์…ฐํ”„ ๐Ÿง‘โ€๐Ÿณ

์„œ๋น„์Šค๋Š” ์‹ค์ œ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง(๋ฐ์ดํ„ฐ ์ €์žฅ, ๊ณ„์‚ฐ, API ํ˜ธ์ถœ ๋“ฑ) ์„ ์ฑ…์ž„์ ธ. ์ปจํŠธ๋กค๋Ÿฌ๊ฐ€ ์–ด๋–ค HTTP ๋ฉ”์†Œ๋“œ๋กœ ํ†ต์‹ ํ•˜๋Š”์ง€ ์ „ํ˜€ ๋ชฐ๋ผ๋„ ๋ผ.

import { Injectable } from '@nestjs/common';
 
@Injectable() // "์ด ํด๋ž˜์Šค๋Š” ๋‹ค๋ฅธ ๋ฐ์„œ ๋ถˆ๋Ÿฌ๋‹ค ์“ธ ์ˆ˜ ์žˆ๋Š” ์ฃผ๋ฐฉ์žฅ์ž…๋‹ˆ๋‹ค"
export class UsersService {
  findAllUsers() {
    // ์‹ค์ œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์กฐํšŒ๋ฅผ ์—ฌ๊ธฐ์„œ ์ˆ˜ํ–‰
    return [{ id: 1, name: 'Suyeong' }]; 
  }
}

๐Ÿ“‹ ์šฉ์–ด: Provider โ€” NestJS์—์„œ ์˜์กด์„ฑ ์ฃผ์ž…์„ ํ†ตํ•ด ๋‹ค๋ฅธ ํด๋ž˜์Šค์— ๊ณต๊ธ‰(provide)๋  ์ˆ˜ ์žˆ๋Š” ๋ชจ๋“  ๊ฒƒ. ์„œ๋น„์Šค๋Š” Provider์˜ ๊ฐ€์žฅ ๋Œ€ํ‘œ์ ์ธ ์ข…๋ฅ˜์•ผ.

3. ๋ชจ๋“ˆ (Module) โ€” ์ฃผ๋ฐฉ๊ณผ ํ™€์„ ํ•˜๋‚˜๋กœ ๋ฌถ์€ ๋ ˆ์Šคํ† ๋ž‘ ์ง€์  ๐Ÿข

๋ชจ๋“ˆ์€ ์„œ๋กœ ์—ฐ๊ด€๋œ ์ปจํŠธ๋กค๋Ÿฌ์™€ ์„œ๋น„์Šค๋ฅผ ํ•˜๋‚˜์˜ ํด๋”์ฒ˜๋Ÿผ ๋ฌถ์–ด์ฃผ๋Š” ๊ป๋ฐ๊ธฐ์•ผ. "Users ๊ด€๋ฆฌ ์ง€์ ", "๊ฒŒ์‹œ๊ธ€ ๊ด€๋ฆฌ ์ง€์ " ๋‹จ์œ„๋กœ ๋‚˜๋‰˜์ง€.

import { Module } from '@nestjs/common';
import { UsersController } from './users.controller';
import { UsersService } from './users.service';
 
@Module({
  controllers: [UsersController],  // ์ด ๋ชจ๋“ˆ์˜ ์›จ์ดํ„ฐ๋“ค ๋“ฑ๋ก
  providers: [UsersService],       // ์ด ๋ชจ๋“ˆ์˜ ์…ฐํ”„๋“ค ๋“ฑ๋ก
})
export class UsersModule {}

4. ์˜์กด์„ฑ ์ฃผ์ž… (DI; Dependency Injection) ๐Ÿ’‰

NestJS๋ฅผ ์ฒ˜์Œ ๋ฐฐ์šธ ๋•Œ ์ œ์ผ ํ—ท๊ฐˆ๋ฆฌ๋Š” ๋‹จ์–ด์•ผ.

โŒ ์˜์กด์„ฑ ์ฃผ์ž…์„ ์•ˆ ์“ฐ๋ฉด?
์ปจํŠธ๋กค๋Ÿฌ๊ฐ€ ์ง์ ‘ ์„œ๋น„์Šค๋ฅผ ์ƒ์„ฑํ•ด์•ผ ํ•ด. (new UsersService())
์ด๋Ÿฌ๋ฉด ์›จ์ดํ„ฐ๊ฐ€ ์ถœ๊ทผํ•  ๋•Œ๋งˆ๋‹ค ์ž๊ธฐ ์ „๋‹ด ์…ฐํ”„๋ฅผ ์ง์ ‘ ๊ณ ์šฉํ•ด์„œ ๋ฐ๋ฆฌ๊ณ  ์™€์•ผ ํ•ด. ์…ฐํ”„๋ฅผ ๋ฐ”๊พธ๊ฑฐ๋‚˜ ํœด๊ฐ€ ๋ณด๋‚ผ ๋•Œ ๋„ˆ๋ฌด ๋ถˆํŽธํ•˜์ง€.

โœ… ์˜์กด์„ฑ ์ฃผ์ž…์„ ์“ฐ๋ฉด?
NestJS(๋ ˆ์Šคํ† ๋ž‘ ์ง€๋ฐฐ์ธ)๊ฐ€ ๋ฏธ๋ฆฌ ์…ฐํ”„ ์ธ์Šคํ„ด์Šค๋ฅผ ํ•˜๋‚˜ ๋งŒ๋“ค์–ด๋‘๊ณ , ์›จ์ดํ„ฐ๊ฐ€ ์ถœ๊ทผ(constructor)ํ•˜๋ฉด ์•Œ์•„์„œ ๋”ฑ ์—ฐ๊ฒฐํ•ด์ค˜!

๐Ÿ’ก ํ•œ ์ค„๋กœ ๊ธฐ์–ตํ•˜๊ธฐ

์ปจํŠธ๋กค๋Ÿฌ๋Š” ์›จ์ดํ„ฐ(์š”์ฒญ/์‘๋‹ต), ์„œ๋น„์Šค๋Š” ์…ฐํ”„(์‹ค์ œ ๋กœ์ง), ๋ชจ๋“ˆ์€ ๋ ˆ์Šคํ† ๋ž‘์˜ ํŠน์ • ์ฝ”๋„ˆ, DI๋Š” ์ง€๋ฐฐ์ธ(ํ•„์š”ํ•œ ์ธ๋ ฅ์„ ์•Œ์•„์„œ ๊ฝ‚์•„์คŒ)์ด์•ผ.


๐Ÿงช ๋”ฐ๋ผํ•ด๋ณด๊ธฐ: ์ฒซ ์•ฑ ์‹คํ–‰ ๋ฐ ๊ตฌ์กฐ ํŒŒ์•…

๋ฐฑ๋ฌธ์ด ๋ถˆ์—ฌ์ผํƒ€! ํ„ฐ๋ฏธ๋„์„ ์—ด๊ณ  ์ง์ ‘ ์ฒซ ์•ฑ์„ ๋„์›Œ๋ณด์ž.

1๏ธโƒฃ ์‹ค์Šต: NestJS ํ”„๋กœ์ ํŠธ ์ƒ์„ฑํ•˜๊ธฐ

# 1. NestJS CLI ๋„๊ตฌ๋ฅผ ์ด์šฉํ•ด ์ƒˆ ํ”„๋กœ์ ํŠธ ๋งŒ๋“ค๊ธฐ (์ด๋ฆ„: my-server)
npx @nestjs/cli new my-server --strict
# โ””โ”€โ”€ --strict: TypeScript์˜ ์—„๊ฒฉํ•œ ๋ชจ๋“œ๋ฅผ ์ผœ์„œ ๋‚˜์ค‘์— ๋ฐœ์ƒํ•  ์—๋Ÿฌ๋ฅผ ์ค„์—ฌ์คŒ
 
# 2. ํด๋”๋กœ ์ด๋™
cd my-server
 
# 3. ๊ฐœ๋ฐœ ๋ชจ๋“œ๋กœ ์„œ๋ฒ„ ์‹คํ–‰ (์ฝ”๋“œ ๋ณ€๊ฒฝ ์‹œ ์ž๋™ ์žฌ์‹œ์ž‘)
npm run start:dev

์„œ๋ฒ„๊ฐ€ ์ผœ์ง€๋ฉด ๋ธŒ๋ผ์šฐ์ €์—์„œ http://localhost:3000์œผ๋กœ ์ ‘์†ํ•ด๋ด. "Hello World!"๊ฐ€ ๋ณด์ผ ๊ฑฐ์•ผ!

๐Ÿ” src/main.ts ํ•œ ์ค„์”ฉ ๋œฏ์–ด๋ณด๊ธฐ:

์ด ํŒŒ์ผ์€ ์„œ๋ฒ„๋ฅผ ์ผœ๋Š” ์—”์ง„ ๋ฃธ์ด์•ผ.

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
 
async function bootstrap() {
  // 1. AppModule(์ตœ์ƒ์œ„ ๋ ˆ์Šคํ† ๋ž‘ ๋ณธ์ )์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์•ฑ ์ƒ์„ฑ
  const app = await NestFactory.create(AppModule);
  
  // 2. 3000๋ฒˆ ํฌํŠธ์—์„œ ์š”์ฒญ์„ ๋Œ€๊ธฐ
  await app.listen(3000);
}
bootstrap(); // ํ•จ์ˆ˜ ์‹คํ–‰

โœ… ์‹ค์Šต ํ›„ ์ฒดํฌ๋ฆฌ์ŠคํŠธ

  • ๋ธŒ๋ผ์šฐ์ €์—์„œ Hello World๋ฅผ ํ™•์ธํ–ˆ๋‹ค.
  • NestJS์˜ 4๋Œ€ ํ•ต์‹ฌ ๊ฐœ๋…(์ปจํŠธ๋กค๋Ÿฌ, ์„œ๋น„์Šค, ๋ชจ๋“ˆ, DI)์„ ๋น„์œ ๋กœ ์„ค๋ช…ํ•  ์ˆ˜ ์žˆ๋‹ค.

๐Ÿ’ผ ๋ฒ ์ŠคํŠธ ํ”„๋ž™ํ‹ฐ์Šค์™€ ์‹ค๋ฌด ํŒ ๐ŸŸก

ํ„ฐ๋ฏธ๋„ CLI๋กœ ๋ณด์ผ๋Ÿฌํ”Œ๋ ˆ์ดํŠธ ๋ฐ•์‚ด๋‚ด๊ธฐ

NestJS๋Š” ํŒŒ์ผ์„ ์ง์ ‘ ๋งŒ๋“ค์ง€ ์•Š์•„๋„ ๋ผ. CLI๊ฐ€ ๋ชจ๋“ˆ, ์ปจํŠธ๋กค๋Ÿฌ, ์„œ๋น„์Šค๋ฅผ ํ•œ ๋ฒˆ์— ์˜ˆ์˜๊ฒŒ ๋ฌถ์–ด์„œ ์ƒ์„ฑํ•ด์ค˜.

# Users์™€ ๊ด€๋ จ๋œ CRUD ์™„๋ฒฝ ์„ธํŠธ ๋ผˆ๋Œ€ ์ƒ์„ฑ!
npx nest generate resource users

์ด ๋ช…๋ น์–ด ํ•œ๋ฐฉ์ด๋ฉด users.controller.ts, users.service.ts, users.module.ts, ๊ทธ๋ฆฌ๊ณ  ํ…Œ์ŠคํŠธ ํŒŒ์ผ๊นŒ์ง€ ์™„๋ฒฝํ•œ ๊ตฌ์กฐ๋กœ ์ƒ์„ฑ๋ผ. ๋ฌด์กฐ๊ฑด ์ด๊ฑฐ ์จ!

์ ˆ๋Œ€ ๊ฒฝ๋กœ (Paths) ์„ค์ •ํ•˜๊ธฐ

ํ”„๋กœ์ ํŠธ๊ฐ€ ์ปค์ง€๋ฉด import { UsersService } from '../../../../modules/users/users.service' ๊ผด์ด ๋‚˜. ๋”์ฐํ•˜์ง€?
tsconfig.json์— ์•„๋ž˜์ฒ˜๋Ÿผ ์„ธํŒ…ํ•ด.

{
  "compilerOptions": {
    "baseUrl": "./",
    "paths": {
      "@/*": ["src/*"]
    }
  }
}

์ด์ œ import { UsersService } from '@/modules/users/users.service' ๋กœ ๊น”๋”ํ•˜๊ฒŒ ๋!


๐Ÿ’ฅ ์—๋Ÿฌ ํ•ด๊ฒฐ ์นดํƒˆ๋กœ๊ทธ

์—๋Ÿฌ ๋ฉ”์‹œ์ง€๊ฐ€ ๋œจ๋ฉด Ctrl+F๋กœ ๋ฉ”์‹œ์ง€ ์ผ๋ถ€๋ฅผ ๊ฒ€์ƒ‰ํ•ด๋ด.

โŒ Error: listen EADDRINUSE: address already in use :::3000

์–ธ์ œ ๋‚˜์˜ค๋Š”๊ฐ€?

[ExceptionsHandler] listen EADDRINUSE: address already in use :::3000

์›์ธ: ์ด๋ฏธ 3000๋ฒˆ ํฌํŠธ์—์„œ ๋‹ค๋ฅธ ์„œ๋ฒ„๊ฐ€ ๋Œ๊ณ  ์žˆ๋‹ค๋Š” ๋œป์ด์•ผ. (์–ด์ œ ์ผœ๋‘” ํ„ฐ๋ฏธ๋„ ์ฐฝ์ด ์–ด๋”˜๊ฐ€ ์‚ด์•„์žˆ์„ ํ™•๋ฅ  99%)

ํ•ด๊ฒฐ์ฑ…:

# Mac/Linux ํ„ฐ๋ฏธ๋„์—์„œ: 3000 ํฌํŠธ ์ฃฝ์ด๊ธฐ
lsof -i :3000
kill -9 [PID๋ฒˆํ˜ธ]

โŒ Nest can't resolve dependencies of the UsersController

์–ธ์ œ ๋‚˜์˜ค๋Š”๊ฐ€?

Nest can't resolve dependencies of the UsersController (?). 
Please make sure that the argument UsersService at index [0] is available in the UsersModule context.

์›์ธ: ์ปจํŠธ๋กค๋Ÿฌ์—์„œ UsersService๋ฅผ ๊ฐ€์ ธ๋‹ค ์“ฐ๊ณ  ์‹ถ์€๋ฐ, NestJS ๊ทœ์น™ ์ƒ ํ•ด๋‹น ๋ชจ๋“ˆ์˜ providers: [] ๋ฐฐ์—ด์— ๋“ฑ๋ก์„ ์•ˆ ํ•ด๋‘” ๊ฑฐ์•ผ. (์…ฐํ”„๋ฅผ ๊ณ ์šฉ ์•ˆ ํ•˜๊ณ  ์›จ์ดํ„ฐ๋งŒ ๋ถˆ๋ €์Œ)

ํ•ด๊ฒฐ์ฑ…:
users.module.ts ํŒŒ์ผ์„ ์—ด์–ด์„œ ์•„๋ž˜์ฒ˜๋Ÿผ ์ˆ˜์ •ํ•ด.

@Module({
  controllers: [UsersController],
  providers: [UsersService], // ๐Ÿ‘ˆ ์ด๊ฑฐ ๋นผ๋จน์—ˆ์–ด!
})

๐Ÿ—‚๏ธ ์น˜ํŠธ์‹œํŠธ

๋ฌธ์„œ ์ „์ฒด๋ฅผ ๋‹ค์‹œ ์ฝ์„ ์‹œ๊ฐ„์ด ์—†์„ ๋•Œ ์ด๊ฒƒ๋งŒ ๋ด๋„ ๋ผ.

๐Ÿ“‹ ํ•ต์‹ฌ ๋ช…๋ น์–ด

์ƒํ™ฉ๋ช…๋ น์–ด์„ค๋ช…
์ƒˆ ํ”„๋กœ์ ํŠธnpx @nestjs/cli new [์ด๋ฆ„]๊ธฐ๋ณธ ๋ผˆ๋Œ€ ์ƒ์„ฑ
์ž์› ์ผ๊ด„ ์ƒ์„ฑnpx nest g resource [์ด๋ฆ„]์ปจํŠธ๋กค๋Ÿฌ+์„œ๋น„์Šค+๋ชจ๋“ˆ ๋š๋”ฑ
๊ฐœ๋ฐœ ์„œ๋ฒ„ ์‹คํ–‰npm run start:devํŒŒ์ผ ์ €์žฅ ์‹œ ์ž๋™ ์žฌ์‹œ์ž‘ ๋ชจ๋“œ

โš ๏ธ ์ ˆ๋Œ€ ํ•˜์ง€ ๋ง ๊ฒƒ

์ƒํ™ฉโŒ ๋‚˜์œ ์˜ˆโœ… ์ข‹์€ ์˜ˆ
์ปจํŠธ๋กค๋Ÿฌ ์—ญํ• ์ปจํŠธ๋กค๋Ÿฌ์—์„œ ํŒŒ๋ผ๋ฏธํ„ฐ ๊ณ„์‚ฐ, DB ์ ‘์†์„œ๋น„์Šค ํ•จ์ˆ˜๋งŒ ๋œ๋  ํ˜ธ์ถœ
์˜์กด์„ฑ ์ƒ์„ฑnew UsersService()constructor(private usersService: UsersService)

๐Ÿ“ ๋งˆ๋ฌด๋ฆฌ ํ€ด์ฆˆ

Q1. ๋‹ค์Œ ์ค‘ NestJS ์ปจํŠธ๋กค๋Ÿฌ์™€ ์„œ๋น„์Šค์˜ ์—ญํ•  ๋ถ„๋‹ด์œผ๋กœ ๊ฐ€์žฅ ์˜ฌ๋ฐ”๋ฅธ ๊ฒƒ์€?

  • A) ์„œ๋น„์Šค๊ฐ€ HTTP API์˜ URL ์ฃผ์†Œ๋ฅผ ์ •์˜ํ•˜๊ณ , ์ปจํŠธ๋กค๋Ÿฌ๊ฐ€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ๊ฐ’์„ ์กฐํšŒํ•œ๋‹ค.
  • B) ์ปจํŠธ๋กค๋Ÿฌ๊ฐ€ HTTP ์š”์ฒญ๊ณผ ์‘๋‹ต์„ ๊ด€๋ฆฌํ•˜๊ณ , ์„œ๋น„์Šค๊ฐ€ ๋ฐ์ดํ„ฐ ์œ ํšจ์„ฑ์„ ๊ฒ€์‚ฌํ•˜๊ณ  ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ๋‹ค๋ฃฌ๋‹ค.
  • C) ์ปจํŠธ๋กค๋Ÿฌ์™€ ์„œ๋น„์Šค ์ค‘ ์•„๋ฌด ๊ณณ์—๋‚˜ ๋กœ์ง์„ ์ž‘์„ฑํ•ด๋„ ๋ฌด๋ฐฉํ•˜๋‹ค.
  • D) ์ปจํŠธ๋กค๋Ÿฌ๋Š” ๋ทฐ(View) ๋ Œ๋”๋ง์—๋งŒ ์‚ฌ์šฉ๋œ๋‹ค.

โœ… ์ •๋‹ต: B

๐Ÿ’ก ์„ค๋ช…: ์›จ์ดํ„ฐ(์ปจํŠธ๋กค๋Ÿฌ)๋Š” ํด๋ผ์ด์–ธํŠธ ๊ตฌ์—ญ, ์…ฐํ”„(์„œ๋น„์Šค)๋Š” ์š”๋ฆฌ ๋กœ์ง. ์ฒ ์ €ํ•˜๊ฒŒ ์—ญํ• ์„ ๋ถ„๋ฆฌํ•ด์•ผ ํ•ด!

Q2. ์•„๋ž˜ ๋นˆ์นธ์„ ์ฑ„์›Œ๋ด.

ํ„ฐ๋ฏธ๋„์—์„œ ๋ช…๋ น์–ด ํ•œ ์ค„๋กœ ์ปจํŠธ๋กค๋Ÿฌ, ์„œ๋น„์Šค, DTO ํŒŒ์ผ ๋“ฑ์„ ํ•œ ๋ฌถ์Œ์œผ๋กœ ์™„๋ฒฝํ•˜๊ฒŒ ์ž๋™ ์ƒ์„ฑํ•˜๊ณ  ์‹ถ์„ ๋•Œ ์“ฐ๋Š” ๋ช…๋ น์–ด๋Š”?

npx nest g [          ] users

โœ… ์ •๋‹ต: resource
๐Ÿ“Œ ํ•ต์‹ฌ ๊ธฐ์–ต๋ฒ•: ๊ฒŒ์‹œํŒ, ์œ ์ €๊ด€๋ฆฌ ๊ฐ™์€ ํ•œ ๋ฉ์–ด๋ฆฌ์˜ '์ž์›(resource)'์„ ํ†ต์งธ๋กœ ์ƒ์„ฑํ•ด์ฃผ๋Š” ๋งˆ๋ฒ•์˜ ๋‹จ์–ด.

Q3. ๋””๋ฒ„๊น… ํ€ด์ฆˆ: ์•„๋ž˜ ์ฝ”๋“œ์—์„œ ์„œ๋ฒ„๊ฐ€ ์ฃฝ๋Š” ์ด์œ ๋ฅผ ์ฐพ์•„๋ด.

// users.module.ts
import { Module } from '@nestjs/common';
import { UsersController } from './users.controller';
 
@Module({
  controllers: [UsersController]
  // ์ฃผ๋ฐฉ์žฅ์ด ์—†์–ด์š”...
})
export class UsersModule {}

์ปจํŠธ๋กค๋Ÿฌ์—์„œ UsersService๋ฅผ ์ฃผ์ž…๋ฐ›์•„ ์“ฐ๊ณ  ์žˆ๋Š”๋ฐ, ๋ชจ๋“ˆ์—๋Š” ์œ„์ฒ˜๋Ÿผ๋งŒ ๋“ฑ๋ก๋˜์–ด ์žˆ์–ด. ์–ด๋–ป๊ฒŒ ๊ณ ์ณ์•ผ ํ• ๊นŒ?

  • A) @Controller ์˜ต์…˜์œผ๋กœ ์„œ๋น„์Šค๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค.
  • B) providers: [UsersService] ๋ฐฐ์—ด์„ ๋ชจ๋“ˆ์— ๋ช…์‹œํ•ด ์ค€๋‹ค.
  • C) imports: [UsersService]๋กœ ์„œ๋น„์Šค ํŒŒ์ผ์„ ๊ฐ€์ ธ์˜จ๋‹ค.

โœ… ์ •๋‹ต: B

๐Ÿ’ก ์„ค๋ช…: ์ž์‹ ์ด ๋ฐ๋ฆฌ๊ณ  ์žˆ๋Š” ์…ฐํ”„(Service)๋Š” ๋ฌด์กฐ๊ฑด Provider ๋ฐฐ์—ด์— ๋ช…์‹œํ•ด์ค˜์•ผ NestJS์˜ DI ์‹œ์Šคํ…œ์ด ์ธ์‹ํ•ด!


๐Ÿ”— ๋” ์•Œ์•„๋ณด๊ธฐ