간단한 인스타그램을 모방한 웹앱을 만들고 있다.
프론트에서는 타입스크립트 뷰 를 만들었고, 백엔드작업에서는 typescript+express 로 개발중이다.
서버개발캠프 4기 활동중에 타입스크립트를 좋게 썼던 경험으로 typescript를 이용해서 견고하고 꼼곰하게 설계를 해보는게 목표다!
인증+멤버십 서버를 설계하던중, 이전까지는 Layered-Architecture에 별로 신경을 쓰지 못했다. 이번에는 3계층으로 서버를 설계하기로 했다.
src
└──app.ts # App class 정의
└──server.ts # App entry point
└──config/ # 환경변수나 각 종 configuration을 수행하는 클래스들 정의
└──controllers/ # 라우팅에 해당하는 클래스들을 정의
└──dtos/ # 컨트롤러에서 서비스간 데이터 교환을 위한 DTO 클래스들 정의
└──entities/ # typeORM DAO 클래스들 정의
└──exceptions/ # 에러핸들링 처리를 위한 클래스들 정의
└──interfaces/ # 각종 인터페이스들 정의
└──middlewares/ # validate, auth 등의 미들웨어 정의
└──routes/ # 라우팅 클래스들을 정의
└──services/ # 비지니스 로직을 위한 서비스 클래스들 정의
알고있는 지식으로 최대한 잘 설계해보려고 디렉토리 구조를 나누었다.
처음으로 계층을 3개로 나누고, 의존성도 신경쓰려다보니 처음에는 코딩할때 많이 어색했던것 같다.
그래도 스켈레톤을 먼저 작성하고 코딩하다보니 익숙해진것 같다.
import { IsEmail, IsString } from 'class-validator';
class CreateUsersDto {
@IsEmail()
public email : string;
@IsString()
public nickname : string;
@IsString()
public pw : string;
}
class-validate 같은 경우에는 데코레이터와 비 데코레이터를 통해서 validate를 수행할 수 있다.
import { plainToClass } from 'class-transformer';
import { validate, ValidationError } from 'class-validator';
import { RequestHandler } from 'express';
import HttpException from '../exceptions/HttpException';
function validationMiddleware(type: any, skipMissingProperties = false): RequestHandler {
return (req, res, next) => {
validate(plainToClass(type, req.body), { skipMissingProperties })
.then((errors: ValidationError[]) => {
if (errors.length > 0) {
const message = errors.map((error: ValidationError) => Object.values(error.constraints)).join(', ');
next(new HttpException(400, message));
} else {
next();
}
});
};
}
body에 담긴 데이터들을 검증하는 미들웨어이다. type으로 들어오는 오브젝트가 앞서 데코레이터를 통해 정의한 값과 일치하는지 검증한다.
자바스크립트에는 두 종류의 객체가 존재한다.
class-transfer에 정의된 plaintToClass 메서드를 통하여 plain object 를 class object로 변경할 수 있다.
객체를 직렬화,역직렬화 하는 이유와 비슷하다고 볼 수 있다. body에 들어온 json 데이터를 다른 클래스와 매핑을 시켜 사용할 수 있기 때문.
true로 설정할 경우, null이나 undefined인 속성들을 무시한다.
false의 경우 그 반대
화하
근데 진짜 누구인가~? 서캠인 것만 알겠는데
타입스크립트하면 기장형인 것 같은데