이번 클론코딩 시간에는 방대한 양의 지식이 한꺼번에 흘러들어와..2번에 걸쳐서 정리를 해보려고 한다.
- Programming Language
TypeScript- Framework
NestJS- API 설계
GraphQL and Apollo- Database & Relevant
PostgresQL & TypeORM
NestJS에서 대표적으로 모듈이 사용되는 방식이며, 정적 모듈 바인딩을 통해 의존성 주입을 할 수 있다.
여기서 의존성 주입
을 간단하게 설명하자면, 두 가지 이상의 모듈을 서로 묶어 하나가 다른 하나 이상의 결과 값에 따라 다른 결과를 가지는 것을 뜻한다.
=> 추후, 클론코딩이 종류된 후 NestJS를 더욱 더 깊이 다룰 때 알아보려고 한다.
@Module({
imports: [AuthService],
providers: [UsersService, UsersResolver],
exports: [UsersService],
})
다시 정적모듈 설명으로 돌아와서 상위의 코드는 정적 모듈의 대표적인 예이다.
정적으로 짜여져 있는 코드들을 Imports
및 Exports
를 하여 그 내부에 클래스를 인스턴스화 하여 메서드를 쓸 수 있게끔 도와준다.
정적 모듈 바인딩을 사용하면 사용 모듈이 호스트 모듈의 providers
에 영향을 미칠 기회가 없기에 동적 모듈을 통해서 이를 극복합니다.
간단하게 코드를 통해서 설명하자면,
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { User } from './entities/user.entity';
import { UsersResolver } from './users.resolver';
import { UsersService } from './users.service';
@Module({
imports: [TypeOrmModule.forFeature([User])],
providers: [UsersService, UsersResolver],
exports: [UsersService],
})
export class UsersModule {}
상기 코드에서 TypeOrmModule
은 동적 모듈 역할을 하는데, forFeature
이란 메서드를 통해 인자로 어떤 것을 받느냐에 따라 모듈에 영향을 줄 수 있다.
누구나 다 한 번쯤은 사용해 봤을 법한 미들웨어
필자도 ExpressJS
에서 Middleware Function
을 만들어 다음과 같이 클라이언트에서 요청이 들어왔을 때 걸러내는 미들웨어를 거치도록 구현한 적이 있다.
const express = require('express');
const { paymentController } = require('../controllers');
const { loginRequired } = require('../utils/auth');
const paymentRoutes = express.Router();
paymentRoutes.post('/approval', loginRequired, paymentController.finalizePayment);
module.exports = { paymentRoutes };
위 코드를 잠깐 보면, paymentController
의 finalizePayment
로직에 접근하기 위해서는 loginRequired
라는 미들웨어를 지나야지만 접근이 되므로 로그인을 하지 못한 사람들은 결제를 할 수 없게 된다.
NestJS
에서도 비슷하게 Middleware
를 설정할 수 있는데 한 가지 큰 차이가 있다면, 구조를 가지고 있기 때문에 정해진 방식으로만 Middleware
를 구현 할 수 있다.
그렇기에 다음 코드 예제를 통해서 알아보도록 하자.
// class middleware
@Injectable()
export class JwtMiddleware implements NestMiddleware {
use(req: Request, res: Response, next: NextFunction) {
if ("x-jwt" in req.headers) {
const token = req.headers["x-jwt"];
}
next();
}
}
//Class로 Middleware 사용해야 할 시
export class AppModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
consumer.apply(JwtMiddleware).forRoutes({
path: "/graphql",
method: RequestMethod.ALL,
});
}
}
export function logger(req: Request, res: Response, next: NextFunction) {
console.log(`Request...`);
next();
};
//function으로 Middleware 사용해야 할 시
app.use(logger);
상위 코드는 Class
로 미들웨어를 구현한 것과 function
으로 미들웨어를 구현한 것이다.
path
는 무시 할 수 있다.사실, 위 설명이 전부는 아니지만 알게 된 것을 그나마 간략하게 표현하는 시간을 가지는 것이기 때문에 더욱 자세하게 파고드는 것은 다음 기회에 NestJS 시리즈를 시작하면서 다루게 될 것 같다.