Nestjs는 NodeJs를 기반에 둔 웹 API 프레임워크이다. 이것은 Express 또는 Fastify 프레임워크를 래핑하여 동작한다. 하지만 기본으로 Fastify를 사용하지 않고 가장 널리 사용되고 있는 Express가 사용되고 있다.
NodeJs는 손쉽게 사용할 수 있지만 과도한 유연함으로 인해 알맞은 라이브러리를 찾기 위해 많은 시간을 할애하여야 한다. 이에 반해 Nestjs에서는 모듈/컴포넌트 기반으로 프로그램을 작성함으로써 재사용성을 높인다. 또한 객체 지향 개념을 도입하였다.
| 구분 | Express | NestJs |
|---|---|---|
| 유연함/확장성 | 가벼운 테스트용 서버를 띄울 수 있음. 자유도가 높은만큼 맞는 라이브러리를 찾기 위해 수고가 필요함 | 미들웨어, IoC, CQRS 등 많은 기능이 포함 원하는 기능이 없다면 다른 라이브러리를 적용하여 사용 가능 |
| 타입스크립트 지원 | 추가설정을 통해 사용 가능 | 기본으로 내장되어있음 |
| 커뮤니티 | 가장 큼 | 꾸준히 증가 중 |
npm i -g @nestjs/cli - 패키지 설치
nest new project-name - 프로젝트 생성
npm run start:dev - 프로젝트 실행
요청 유효성 검사 - 프론트엔드에서 들어오는 요청이 잘못된 값이 전달된 경우라면 400 Bad Request로 응답해야한다.
인증 - 사용자의 리소스에 접근하기 위해서 권한이 필요하고 로그인 과정을 거쳐야 한다. 토큰 방식에서는 주로 JWT를 사용한다.
로깅 - 서버의 상태가 양호한지 주기적으로 검사해야한다. 상태가 좋지 않다면 경고를 발생시켜야 한다.
CQRS - 복잡한 코드가 생기는 경우가 있기에 데이터베이스에 변형을 가하는 명령과 데이터 읽기 요청을 처리하는 조회 로직을 분리함으로써 성능, 확장성을 강화할 수 있다.
클린 아키텍처 : 클린 아키텍처는 SW의 계층을 분리하고 저수준의 계층이 고수준의 계층에 의존하도록 한다.
단위 테스트 : 단위 테스트는 개발자가 테스트 코드를 이용하여 수행하는 최소 단위 테스트 기법이다.
예전의 웹페이지에서 구동되는 애플리케이션은 모두 SSR(server-side rendering) 방식으로 동작했다. 이 방식은 서버가 요청을 처리한 다음 HTML과 자바스크립트 응답을 브라우저에 전송하면 브라우저는 서버로부터 전달되는 HTML 코드를 화면에 뿌려주기만 하면 됐었다.
리액트가 큰 인기를 얻으면서 SPA 기반으로 구축된 서비스가 늘어났다. 이 방식은 서버로부터 매 요청에 대한 최소한의 데이터만 응답으로 받고 화면 구성 로직을 프론트에서 처리한다.
시간이 지날수록 웹 기술은 점점 발전했고, 자연스럽게 개발에 필수적인 요소들을 묶어 쉽게 쓸 수 있고자 하는 시도가 생겨났다 = 웹 프레임워크
자바스크립트는 이전까지 프론트엔드에서 사용하는 언어라는 인식이 강하였고, 실제 script 태그를 주로 삽입하여 사용하였다. 하지만 이것은 보안에 취약하다는 문제점이 있었다. 하지만 Nodejs 등장으로 인해 자바스크립트를 이용하여 서버를 구동할 수 있게 되었다.
따라서 프론트엔드와 백엔드에서 같은 언어를 사용한다는 것은 큰 장점이다.
여러 작업 요청이 한꺼번에 들어올 때, 각 작업을 처리하기 위한 스레드를 만들고 할당하는 방식을 멀티스레딩이라고 한다. 이 방식은 동시에 여러 작업을 수행하므로 속도는 빠르지만 잘못 작성하게 된다면 락에 빠질 수 있다. 스레드가 늘어날수록 메모리를 소비하게 된다.
이에 비해 Nodejs는 하나의 스레드에서 작업을 처리한다. 앞의 작업이 끝날 때까지 기다리지 않고(non-blocking 방식) 비동기로 처리한다. 입력은 하나의 스레드에서 받지만 순서대로가 아닌 먼저 처리된 결과를 반환하므로 단일 스레드 non-blocking 이벤트 기반 비동기 방식이다.
이벤트 루프는 시스템 커널에서 가능한 작업이 있다면 그 작업을 터널에 관할한다. NodeJs가 단일 스레드이지만 non-blocking 작업을 할 수 있는 핵심 기능이다.
이 부분은 다음에 포스팅으로 자세하게 다룰 예정
package.json의 역할
1. 애플리케이션이 필요로 하는 패키지 목록을 나열한다.
2. 시맨틱 버저닝 규칙으로 필요한 버전을 기술한다.
3. 다른 개발자와 같은 빌드를 구성할 수 있다.
package-lock.json의 역할
1. node_modules나 package.json 파일의 내용이 바뀌면 npm install 명령을 수행할 때 자동 수정된다.
2. package.json에 선언된 패키지들이 설치될 때 정확한 버전과 서로 간의 의존성을 표현한다 => 팀원들 간에 정확한 개발 환경 공유가능
ex) package-lock.json이 이미 존재한다면 npm install시 이 파일을 기준으로 패키지를 설치
자바스크립트 코드에 타입 시스템을 도입하여 런타임에 에러가 발생할 가능성이 있는 코드를 분석하여 런타임에 발생할 오류를 미리 컴파일 타임에 잡아준다.
[선언 키워드][변수명]: [타입]
const - 선언 후 재할당이 불가능
let, var - 재할당이 가능하며 값을 바꿀 수 있다.
let과 var의 차이는 호이스팅 여부이다.
: 객체 타입은 속성을 가지고 있는 데이터 컬렉션이다.
: 자바스크립트는 함수를 변수에 할당하거나 다른 함수의 인수로 전달할 수 있다. 함수의 결과로 반환가능하다. 함수 func의 타입을 검사하면 function이 나온다(일급 함수라고 함)
any - 어떠한 타입의 값도 받을 수 있는 타입
unknown - 어떤 타입도 할당 가능하지만 다른 변수에 할당 또는 사용할 때 타입을 강제 -> any가 일으키는 오류를 줄임
never - 이 타입의 변수에는 어떤 값도 할당할 수 없다. 함수의 리턴 타입으로 지정하면 함수가 어떤 값도 반환하지 않는다.
타입스크립트는 타입을 정의해서 사용한다. 변수에 객체를 바로 할당하지 않고 interface로 선언할 수 있다. 인터페이스를 이용하여 User의 타입을 정의하는 것이다.
// 인터페이스
interface User{
name: string;
age: number;
}
const user: User = {
name: 'Dexter',
age: 21,
}
// 클래스로 선언
class User{
constructor(name: string, age: number){}
}
const user: User = new User('Dexter', 21);
자바스크립트 변수에 어떠한 타입의 값도 할당할 수 있다. 이러한 개념duck typing(덕타이핑)이라 부른다. 여러 타입을 조합한 새로운 타입을 가지는 것이다.
여러 타입을 조합한 타입이다. 한 변수가 string 또는 string[] 타입을 가질 수 있다.
이 유니언 타입을 활용하면 변수가 가질 수 있는 값을 제한할 수 있다.
type Status = "Ready" | "Waiting";
// 위의 코드를 열거형으로 사용
enum Status {
READY = 'Ready',
WAITING = 'Waiting",
}
어떤 타입이든 정의될 수 있지만 호출되는 시점에 타입이 결정된다.
function identity(arg: any): any{
return arg
}
함수의 반환값이 any로 되어 있기 때문에 'test'를 인수로 전달 경우에 전달한 인수의 string 타입이 반환 시 any가 되어버린다. 반면에 제네릭 타입을 사용하게 되면 리턴이 되는 타입은 함수를 호출하는 시점의 인수로 넣은 타입으로 결정되게 된다.
// 보통 제네릭 선언시 대문자 한글자를 사용한다.
function identity<T>(arg: T): T{
return arg;
}
이 포스팅은 NestJs로 배우는 백엔드 프로그래밍 - 한용재 님의 책을 바탕으로 작성되었습니다.
정보 감사합니다.