본문 바로가기

프로그램 개발

NestJS 개발 시작하기(로그인 인증 개발); 1. NestJS와 Spring의 비교

NestJS 개발 시작하기(로그인 인증 개발)

1. NestJS와 Spring의 비교

2. NestJS CLI로 개발시작

3. API개발과 Swagger

4. TypeORM으로 DB연결

5. Session, JWT, OAuth 차이

6. jwt 인증 (1)

7. 암호화와 해쉬 함수

 

 

프로그램 개발은 고객의 요구사항, 시장의 요구사항, 심지어는 유행에 따라 사용하는 소프트웨어, 인프라뿐만 아니라, 프로그래밍 언어도 바뀌는 추세이다. 그래서 필요할 때 꺼내 쓸 수 있도록 프로그래밍 언어에 대한 기억도 기록해 보려고 한다.

0. 개인 경험에 비춘 프로그래밍 언어의 짧은 역사

내 기억으로,   C/C++로 개발할 때는 특정 서버(대표적으로 IBM, HP, Sun 서버 등)에 맞는 바이너리로 컴파일해야 하기 때문에, 컴파일하기 위한 Makefile을 만들기 위해 서버마다 다른 라이브러리와 컴파일러 옵션을 맞추기 위해 고생했던 것 같다. 그래서, 개발자들은 JVM (Java Virtual Machine)이라는 가상머신을 사용해 이런 단점을 개선한 Java에 대해 관심을 가지게 되었고, JIT(Just In Time) Compile방식이 도입되고 런타임에 성능을 개선된 Java버전이 나오면서 Java로 개발언어로 점차 옮겨가게 되었다. Java는 아직도 많은 회사에서 개발에 사용하고 있다.

 

출처) IEEE 2024

IEEE발표에서 보듯, 현재 개발언어의 1위는 딥러닝의 인기에 힘입어 압도적으로 파이썬이 차지하고 있자만, 2위를 고수하고 있는 Java 못지않게 인기 있는 언어는 JavaScript이다. JavaScript는 웹 기술이 발달하면서 브라우저의 DOM을 조작해 HTML페이지를 동적으로 생성할 수 있는 로직을 구현하기 위해 개발되었는데, 처음에는 Event Handler정도의 로직만을 구현하는 데 사용했었다. 하지만, 구글이 워드프로세서를 JavaScript로 만들어 내면서, 개발자들은 브라우저 상의 JavaScript로 복잡한 프로그램도 제작할 수 있다는 확신을 가지게 되었고 프런트엔드(Frontend)가 개발의 한 분야로 자리 잡았다.

 

인터프리터 방식인 JavaScript를 구동하는 JavaScript Engine의 성능이 올라가면서 JavaScript를 좋아하는 사람들이 백엔드(Backend) 개발에도 JavaScript를 사용하기 위해 Node.js 런타임을 만들었고, 특히 적은 인력으로 짧은 기간 안에 개발해야 하는 스타트업들은 Ruby On Rail 이후 MVP(Minimum Viable Product)를 위한 빠른 개발환경에 관심을 가지게 되면서 JavaScript로 프런트엔드와 백엔드를 통합하는 시도를 하기 시작했다. 이 과정에서 전에는 최소 두 개의 언어와 개발에 필요한 프레임워크를 학습한 값비싼 풀 스택(Full Stack) 개발자를 JavaScript 개발자로 바꿀 수 있게 되었다.

 

JavaScript로 풀 스택을 개발하는데 가장 유용한 Framework는 Next.js인데 MVP를 넘어 본격적으로 서비스를 시작하면 Next.js로만 개발하기에는 MSA도입, 전문 조직분리와 같은 문제에서 어려움을 느끼게 되고, 다시 프런트엔드와 백엔드로 나누면서 백엔드 기술로 많이 도입하는 JavaScript Framework가 NestJS이다.

1. Spring 사촌 NestJS

a. Spring Framework에 대한 간단한 설명

Java로 개발하면 1순위로 사용하는 프레임워크가 스프링 프레임워크(Spring Framework) 일 것이다. 효과적인 Java개발을 위해 Enterprise Java Bean, Struts, 등과 같은 많이 시도들이 있었지만, 현재 가장 많은 회사들이 사용하고 있는 것은 Spring Framework이다.

 

Spring 공홈에 가보면 Spring의 특징이

  • Core technologies: dependency injection, events, resources, i18n, validation, data binding, type conversion, SpEL, AOP.
  • Testing: mock objects, TestContext framework, Spring MVC Test, WebTestClient.
  • Data Access: transactions, DAO support, JDBC, ORM, Marshalling XML.
  • Spring MVC and Spring WebFlux web frameworks.
  • Integration: remoting, JMS, JCA, JMX, email, tasks, scheduling, cache and observability.
  • Languages: Kotlin, Groovy, dynamic languages.

로 복잡하게 설명되어 있는데, 개인적으로는 빠른 적응력이라고 생각한다. 새롭게 유행하는 기술이 유행할 때마다 Spring Framework는 그 기술을 신속하고 매끄럽게 수용해서 20년 동안 개발자들의 사랑을 받아왔다.

 

많은 개발자들이 Spring Framework의 핵심기술은 크게 AOP, IoC, MVC 3가지를 선택하는데, 이 기술들이 Spring Framework에서 만들어진 것은 아니고, 오랜 기간 많은 개발자들이 발전시켜 온 기술을 Spring Framework에도 적용했다고 보면 된다.

b. AOP (Aspect Oriented Programming)

AOP에서는 프로그램의 개발 내용을 두 가지 종류의 관심사(concern)로 분류하는데,

  • core concern은 내가 작성하는 module에서 처리해야 하는 비즈니스 로직 중심의 관심사(concern)
  • cross-cutting concern은 Logging이나 보안인증처럼 다른 module에도 적용해야 하는 공통 관심사

로 구분해서, 개발자가 비즈니스 로직 관심사 (core conern)에 더 집중할 수 있도록 분리할 수 있게 도와주는 기술이다. Spring Framework에는 Filter Interceptor가 AOP를 위해 도입되었고, NextJS에는 Guard, Interceptor, Pipe를 통해 AOP를 지원하고 있다.

c. IoC (Inversion Of Control)

IoC가 도입되기 이전에는 모듈을 작성하는 개발자는 해당 모듈(또는 클래스 인스턴스)의 생성과 소멸을 직접 관리했다. C/C++에서 개발자가 메모리 관리를 담당하면서 개발자의 능력에 따라 메모리 관리를 제대로 하지 못할 경우 프로그램 성능이 저하되었던 것처럼, 모듈의 생명주기를 개발자가 관리할 때도 개발자의 능력에 따라 제품의 완성도에 영향을 줄 수 있다.

 

이 문제를 해결하기 위해 IoC이란 개념이 만들어 졌고, IoC(Inversion of Control)를 구현하기 위해 프레임워크는 모듈을 생성하고 이를 다른 모듈에서 사용할 수 있도록 변수에 바인딩하는 과정을 거치게 되며, 이 과정을 DI (Dependency Injection) 라고 한다.

 

결론적으로 IoC를 사용하면 moduel의 생명주기(Life Cycle) 관리가 Framework을 통해 자동으로 관리되기 때문에 개발자는 비즈니스 로직의 개발에 더 집중할 수 있게 된다. Spring Framework @Bean, @Component, @Controller, @Service 등의 어노테이션(annotation)을 사용하여 DI 대상 클래스를 지정하고 @Autowired를 통해 변수에 Binding 하며, NestJS@Module, @Controller, @Service, @Injectable 등의 어노테이션(annotation)을 통해 DI 대상을 지정하고 @Inject로 변수에 Binding 한다.

c. MVC (Model, View, Controller)

AOP와 IoC보다 먼저 등장한 이 개념은 프로그램을 데이터(Model), 화면(View), 그리고 비즈니스 로직(Controller)으로 분리하여 개발함으로써 각 분야의 전문가들이 역할을 분담할 수 있게 하는 개발 기술이다.

 

Spring Framework는 JPA, MyBatis, Hibernate 등을 활용하여 데이터베이스와 연동을 지원함으로써 Model을 구현하고, JSP, JSF, Struts와 같은 SSR(Server Side Rendering) 템플릿 엔진을 사용해 View를 만든다. NestJS에서는 TypeORM, GraphQL 등을 활용하여 모델을 구현할 수 있으며, Handlebars나 파이썬의 Jinja와 유사한 Nunjucks를 템플릿 엔진으로 사용해 View를 구현할 수 있지만 React나 Vue.js를 사용하는 CSR(Client Side Rendering)이 더 일반적인 개발 패턴으로 자리 잡고 있다.

 

NestJS 요청, 응답 구조