framework/NestJS

๐ŸŒ NestJS HTTP Module – ์™ธ๋ถ€ API ์š”์ฒญ ์™„์ „ ์ •๋ณต ๊ฐ€์ด๋“œ

octo54 2025. 6. 23. 12:09
๋ฐ˜์‘ํ˜•

๐ŸŒ NestJS HTTP Module – ์™ธ๋ถ€ API ์š”์ฒญ ์™„์ „ ์ •๋ณต ๊ฐ€์ด๋“œ


NestJS์—์„œ ์™ธ๋ถ€ API ์„œ๋ฒ„(REST, JSON-RPC ๋“ฑ)์™€ ํ†ต์‹ ํ•˜๋ ค๋ฉด
@nestjs/axios ๊ธฐ๋ฐ˜์˜ HTTP ๋ชจ๋“ˆ(HttpModule) ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€์žฅ ๊ฐ„ํŽธํ•˜๊ณ  ๊ฐ•๋ ฅํ•ฉ๋‹ˆ๋‹ค.
Axios ๊ธฐ๋ฐ˜์œผ๋กœ ์ž‘๋™ํ•˜๋ฏ€๋กœ ์ต์ˆ™ํ•œ ๋ฐฉ์‹์œผ๋กœ API ์š”์ฒญ์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๊ณ ,
RxJS ์ŠคํŠธ๋ฆผ๊ณผ๋„ ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ๊ฒฐํ•ฉ๋ฉ๋‹ˆ๋‹ค.

์ด๋ฒˆ ๊ธ€์€ NestJS ๊ณต์‹ ๋ฌธ์„œ - HTTP Module์„ ๋ฐ”ํƒ•์œผ๋กœ
๊ธฐ๋ณธ ์‚ฌ์šฉ๋ฒ•, ๋น„๋™๊ธฐ ์„ค์ •, ์ „์—ญ ๋“ฑ๋ก, RxJS ์‘๋‹ต ์ฒ˜๋ฆฌ๋ฒ•๊นŒ์ง€ ์‹ค๋ฌด ์œ„์ฃผ๋กœ ์•ˆ๋‚ด๋“œ๋ฆฝ๋‹ˆ๋‹ค.


โœ… 1. ์„ค์น˜ ๋ฐ ์ž„ํฌํŠธ

npm install @nestjs/axios axios
import { HttpModule } from '@nestjs/axios';

@Module({
  imports: [HttpModule],
  providers: [MyService],
})
export class MyModule {}

โ˜‘๏ธ HttpService๋Š” @nestjs/axios๊ฐ€ ์ œ๊ณตํ•˜๋Š” ์˜์กด์„ฑ์ž…๋‹ˆ๋‹ค.


โœ… 2. ๊ฐ„๋‹จํ•œ GET ์š”์ฒญ ์˜ˆ์ œ

๋ฐ˜์‘ํ˜•
import { Injectable } from '@nestjs/common';
import { HttpService } from '@nestjs/axios';
import { firstValueFrom } from 'rxjs';

@Injectable()
export class MyService {
  constructor(private readonly httpService: HttpService) {}

  async getUser() {
    const response = await firstValueFrom(
      this.httpService.get('https://jsonplaceholder.typicode.com/users/1'),
    );
    return response.data;
  }
}

โ˜‘๏ธ firstValueFrom()์„ ์‚ฌ์šฉํ•˜์—ฌ RxJS Observable์„ Promise๋กœ ๋ณ€ํ™˜
โ˜‘๏ธ response.data์— ์‹ค์ œ ์‘๋‹ต ๋ณธ๋ฌธ์ด ๋“ค์–ด์žˆ์Šต๋‹ˆ๋‹ค.


๐Ÿ“บ ๊ด‘๊ณ 

์™ธ๋ถ€ API๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ์„œ๋น„์Šค ํ•จ์ˆ˜๋Š” ๋Œ€๋ถ€๋ถ„์˜ ๋ฐฑ์—”๋“œ์—์„œ ํ•ต์‹ฌ์ด ๋˜๋Š” ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค.
์ด ์ง€์ ์€ ์• ๋“œ์„ผ์Šค ๊ด‘๊ณ ๊ฐ€ ๊ฐ€์žฅ ์ง‘์ค‘๋„ ์žˆ๊ฒŒ ๋…ธ์ถœ๋  ์ˆ˜ ์žˆ๋Š” ์œ„์น˜์ž…๋‹ˆ๋‹ค.

<ins class="adsbygoogle"
     style="display:block"
     data-ad-client="ca-pub-XXXXXX"
     data-ad-slot="YYYYYY"
     data-ad-format="auto"
     data-full-width-responsive="true"></ins>

โœ… 3. POST ์š”์ฒญ ๋ฐ ํ—ค๋” ํฌํ•จ

async createPost() {
  const payload = { title: 'New Post', body: '๋‚ด์šฉ', userId: 1 };
  const headers = { 'Authorization': 'Bearer xxx' };

  const response = await firstValueFrom(
    this.httpService.post('https://jsonplaceholder.typicode.com/posts', payload, { headers }),
  );
  return response.data;
}

โ˜‘๏ธ headers ์˜ต์…˜์œผ๋กœ ์ธ์ฆ ํ† ํฐ ๋“ฑ๋„ ์ž์œ ๋กญ๊ฒŒ ์ „๋‹ฌ ๊ฐ€๋Šฅ


โœ… 4. ์ „์—ญ HTTP ์„ค์ • (timeout, baseURL ๋“ฑ)

@Module({
  imports: [
    HttpModule.register({
      timeout: 5000,
      maxRedirects: 5,
      baseURL: 'https://api.example.com',
    }),
  ],
})

โ˜‘๏ธ ๋ชจ๋“  ์š”์ฒญ์— ๊ณตํ†ต ์ ์šฉ๋˜๋Š” ๊ธฐ๋ณธ ์˜ต์…˜ ์„ค์ •


โœ… 5. ๋น„๋™๊ธฐ ๋“ฑ๋ก (useFactory)

HttpModule.registerAsync({
  useFactory: async (configService: ConfigService) => ({
    timeout: configService.get('HTTP_TIMEOUT'),
    baseURL: configService.get('API_BASE_URL'),
  }),
  inject: [ConfigService],
}),

โ˜‘๏ธ .env ์„ค์ • ํŒŒ์ผ์„ ํ†ตํ•ด ๋™์ ์œผ๋กœ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์–ด ์‹ค๋ฌด์—์„œ ๋งค์šฐ ์œ ์šฉ


โœ… 6. RxJS ์—ฐ๋™ ์˜ˆ์ œ (์‘๋‹ต ๊ฐ€๊ณต)

return this.httpService.get('https://api.example.com/data').pipe(
  map((res) => res.data.items),
  catchError((error) => {
    throw new Error('API ์‹คํŒจ: ' + error.message);
  }),
);

โ˜‘๏ธ RxJS๋ฅผ ํ™œ์šฉํ•˜๋ฉด ์ŠคํŠธ๋ฆฌ๋ฐ, ๋ฆฌ์•กํ‹ฐ๋ธŒ ์ฒ˜๋ฆฌ๊ฐ€ ์‰ฌ์›Œ์ง‘๋‹ˆ๋‹ค.


โœ… ์‹ค๋ฌด ์ ์šฉ ํŒ ์š”์•ฝ

์ž‘์—… ๋ฐฉ๋ฒ•

API ์‘๋‹ต Promise ๋ณ€ํ™˜ firstValueFrom() ๋˜๋Š” lastValueFrom() ์‚ฌ์šฉ
๊ณตํ†ต ํ—ค๋”, ํƒ€์ž„์•„์›ƒ register() ๋˜๋Š” registerAsync() ํ™œ์šฉ
์‘๋‹ต ์ŠคํŠธ๋ฆผ ์ฒ˜๋ฆฌ pipe(map(), catchError())๋กœ RxJS ์ŠคํŠธ๋ฆผ ๋ณ€ํ™˜
์ธ์ฆ ์ฒ˜๋ฆฌ Authorization, API-Key ๋“ฑ ํ—ค๋” ์ง์ ‘ ์ง€์ •
์ „์—ญ ๊ณตํ†ต ์—๋Ÿฌ ํ•ธ๋“ค๋ง interceptors ๋˜๋Š” ๊ธ€๋กœ๋ฒŒ ์˜ˆ์™ธ ํ•„ํ„ฐ ์ถ”์ฒœ

 

NestJS HTTP ๋ชจ๋“ˆ,NestJS HttpService ์‚ฌ์šฉ๋ฒ•,NestJS ์™ธ๋ถ€ API ํ˜ธ์ถœ,NestJS axios ์—ฐ๋™,NestJS ๋น„๋™๊ธฐ API ์š”์ฒญ,NestJS HttpModule register,NestJS HttpModule ์ „์—ญ ์„ค์ •,NestJS firstValueFrom,NestJS REST API ์—ฐ๋™,NestJS ์‹ค๋ฌด ์™ธ๋ถ€ ์š”์ฒญ ์ฒ˜๋ฆฌ