Server/Node.js 16

Sequelize - FROM 절에 SubQuery 사용하기 !

SubQuery in FROM clause Sequelize ORM을 사용중인 프로젝트에 FROM 절에 SubQuery를 사용해야 하는 이슈가 생겼다. "Sequelize subquery in from clause" 등의 키워드로 검색해봤는데, 결과가 나오지 않았다 ㅠ 관련해서 어떻게든 삽질해서 검색을 해봤는데 JPA, JPQL, Sequelize 등 대부분의 ORM에서 from 절에서 서브쿼리를 사용하는 것(이하 "인라인뷰")를 지원하지 않는다고 한다. 대처방안으로는 아래와 같은 방법이 있다. 서브쿼리보다는 Join을 사용한다. 쿼리를 2개 이상으로 분리한 후 가공 작업을 한다. 또는 작업을 분할하고 특정 기능은 App Layer나 Presentation Layer에서 수행한다. RawQuery(이하 ..

Server/Node.js 2022.05.05

Sequelize - fn(), literal(), col(), where() 잘 사용하기!

Sequelize.fn() Sequelize.fn()을 사용하면 sql 함수를 쉽게 사용할 수 있습니다. 예시를 몇개 들겠습니다. // SUBSTR(str, pos); sequelize.fn("substr", str, pos); // IFNULL(a, b); sequelize.fn("ifnull", a, b); // SUM(a, b); sequelize.fn("sum", a, b); // CONCAT(a, b); sequelize.fn("concat", a, b); 첫 번째 파라미터로는 함수명을, 두 번째 파라미터부터는 대상을 지정하면 됩니다. function fn(fn: string, ...args: unknown[]): Fn; SELECT에서 사용할 때는 아래와 같이 사용할 수 있습니다. attrib..

Server/Node.js 2022.03.25

Sequelize - SubQuery를 FROM 절에서 사용하기(?)

Sequelize - SubQuery in From clause SQL 함수를 SELECT 절에서 계산된 결과를 WHERE절 조건식에 넣고 싶은 경우가 간혹 있습니다. 예를 들면 아래의 경우 입니다. SELECT * FROM (SELECT CONCAT(first_name, ' ', last_name) AS fullName FROM user) WHERE full_name LIKE '%david%'; 그래서 공을 들여 관련 내용을 어떻게든 찾아봤는데... 결론부터 말씀드리면, 안타깝게도 할 수 없습니다! 아래 이슈를 보시면 많은 분들이 원함에도 불구하고, 해당 기능을 사용할 수 없습니다. https://github.com/sequelize/sequelize/issues/5354 따라서, 아래의 선택들이 있..

Server/Node.js 2022.03.25

Jest - 테스트 코드간 충돌, 간섭 막는 방법 (매번 테스트 결과가 다를 때 해결 방법!)

테스트 코드 충돌 (간섭) 사내에서 jest + supertest를 이용해서 테스트 코드를 작성하고 있었습니다. 그런데, 자꾸 테스트를 돌릴 때마다 한 번씩 테스트가 깨지는 현상이 발생했습니다. 알고보니 테스트 코드 파일 A가 다른 테스트 코드 파일 B랑 비동기로 실행되다 보니까 서로 간섭하는 현상이 생기는 것이었습니다. 상황 충돌을 일으킨 테스트 2가지는 아래와 같습니다. 카테고리 MVC 테스트 상품 MVC 테스트 프로젝트 구조가 상품 등록 API를 테스트할 때는 먼저 카테고리를 생성한 후에 상품 등록 API에 요청을 보내는 구조였습니다. 상품 등록 API는 등록할 카테고리의 id를 받아서, 해당 카테고리가 없으면 예외가 발생하기 때문에 그렇게 설계했습니다. 카테고리 MVC 테스트는 각 테스트가 실행될..

Server/Node.js 2022.02.28

NodeJS - 권한 제어 (Endpoint별 인증, 인가) 하는 법! (+ middleware)

NodeJS 인증, 인가 특정 엔드포인트마다 뭔가를 검증해야 하는 서비스가 있습니다! 예를 들어서, 관리자만 사용할 수 있는 API가 있다거나 하는 경우가 있죠! 그럴 경우에 해당 컨트롤러 메서드에서, 검증을 해서 거를 수도 있습니다. 하지만, 그것보다는 훨씬 직관적인 방법이 있습니다! 바로 Middleware를 이용하는 방법입니다. Middleware 작성 const authenticateAdmin = async (req:Request, res:Response, next:NextFunction) => { if(isSuperAdmin(req.jwt) || await isBookingAdmin(req.jwt)) { return next(); } else{ return next(new HttpExceptio..

Server/Node.js 2022.02.13

Jest - 테스트 환경 구축하는 방법 (Test용 DB 사용) with Setup, Teardown

테스트 환경 구축 현재 프로젝트로 Typescript + NodeJS + Express + MySQL을 이용해서 API를 개발하고 있었습니다. 문제는, 테스트 코드를 작성하는데, 문제가 Java Spring은 H2라는 인메모리 DB가 있는데 NodeJS에서는 사용할 수 있는 라이브러리가 딱히 없었습니다. SqLite가 있지만, Mysql과 규격이 다른 부분이 많아서 정확하게 테스트하기가 힘들었습니다. 그래서 MySQL 서버를 유지할 수 있는 다른 방법을 생각했습니다. [방법 1] Docker compose를 이용해서, 테스트가 진행 시 마다 컨테이너를 down, up 해서 덤프를 생성한 후 테스트 [방법 2] 테스트 전체 실행 전에 데이터를 전부 truncate 후 덤프를 생성 [방법 3] Setup a..

Server/Node.js 2022.02.13

Sequelize - bigint를 사용하는 방법? (+ underscored)

DB에 bigint로 저장된 컬럼을 API에서 꺼내서 그대로 사용하면 바이트 부족으로 인해서 데이터가 손실됩니다..!! Sequelize에서는 아래와 같이 dialectOptions의 supportBigNumbers를 정의해서, 손실을 방지할 수 있고, bigNumberStrings를 정의해서 string으로 받을 수도 있습니다. import { Sequelize } from "sequelize"; const shopDB = new Sequelize( "shopDB", "root", "root", { host: "localhost", dialect: "mysql", pool: { max: 10, min: 0, acquire: 5000, idle: 10000, }, timezone: "+09:00", di..

Server/Node.js 2022.01.11

Sequelize - 커스텀 메서드 (Custom method) 구현

ORM 패턴? ORM은 두 가지 패턴이 있습니다. Active Record (pattern)과 Data Mapper (Repository) pattern입니다. Active Record pattern은 엔터티가 CRUD 기능을 하는 메서드들을 프로퍼티로 가지고 있어서 Model이 자기가 가지고 있는 메서드(쿼리)를 실행하는 형태입니다. 반면, Data Mapper pattern(with Repository)은 모델과 메서드(쿼리)를 분리합니다. Repository를 따로 두고, Repository에서만 메서드를 구현합니다. Sequelize는 Active Record pattern입니다. 즉, 모델이 class method를 가지고 있어야 합니다. 그래서 우리는 User.findAll(), User.up..

Server/Node.js 2022.01.08

Sequelize - 일괄 등록, 일괄 수정 하기 (bulk create, bulk update)

일괄 등록 (bulkCreate) const result = await User.bulkCreate(usersDTO) 일괄 등록의 경우 Sequelize는 bulkCreate 메서드를 지원하고 있습니다. bulkCreate()를 이용해서 배열을 한 번에 insert 칠 수 있습니다. 일괄 수정 (bulkUpdate) Sequelize에서 일괄 수정을 하는 방법은 3가지가 있습니다. 한 가지씩 소개해드리겠습니다 ! 1. update const result = await User.update({ name: updateUsersDto.name }, { where: { id: { [Op.in]: updateUsersDto.users } } }); // UserDTO.ts export interface Updat..

Server/Node.js 2022.01.05

NodeJS - 전역 예외 핸들러 구현 (Custom global exception handler)

전역 예외 핸들러 저의 경우 Sequelize + express + nodejs의 프로젝트를 하고 있었는데, Sequelize가 500번대 예외를 뱉는 경우가 많았습니다. 해당 부분은 App단에서 최대한 검증을 해서 요청을 보내면 좋겠지만, 동시성 문제로 어쩔 수 없이 예외가 발생하기도 합니다. 요즘은 500번대 에러는 핸들링을 하는 것을 원칙으로 하는 기업이 많은 걸로 알고 있습니다. 특히 네이버 특정 계열사 Open API Reference에 보면 500번대 에러가 나오면 제보해달라는 내용이 있기도 하기도 합니다. 따라서, 해당 예외를 핸들링하고 싶었는데, 각 메서드에 여러개의 예외처리를 전부 공통적으로 붙이면 유지보수성이 떨어지니까, 전역 범위로 적용해야 했습니다. 스프링은 @ControllerAd..

Server/Node.js 2021.12.29