GraphQL과 Rest API 동시 사용시 Cannot read property 'headers' of undefined 에러 해결

개발/NestJS 2022. 1. 22. 08:20

레거시는 GraphQL, 추가 개발은 Rest 방식으로 진행되는 NestJs 기반의 백엔드에서 @Public이 아닌 Rest API에서 TypeError: Cannot read property 'headers' of undefined 가 발생하였다. 원인 처음 생각한 원인은 front에서 Rest API를 호출할 때, header에 토큰 정보가 포함되지 않는 것이라고 생각했는데 체크해보니 잘 들어가 있었다. 백엔드에서 JWT를 검증하는 AuthModule에서 백엔드로 들어오는 request를 체크하는 jwt-auth guard에 문제가 있었다. getRequest()메소드가 기존 @nestjs/passport에 포함되어있는 AuthGuard의 getRequest()를 오버라이드해서 GraphQL의 req..

Article Thumbnail
QueryBuilder .leftJoin사용시 원하는 칼럼만 SELECT하기

개발/TypeORM 2022. 1. 17. 08:20

QueryBuilder를 사용하여 JOIN 쿼리가 포함된 쿼리문을 작성하다보면 주로 .leftJoinAndSelect 메소드를 사용한다. .leftJoinAndSelect를 사용하면 하나하나 칼럼을 체크할 필요가 없고, 코드 가시성적인 면에서는 장점이 있었지만, 모든 칼럼을 Select해오다보니 성능적인 면에서 필요한 칼럼만을 가져오는 쿼리에 비해 상대적으로 메모리 사용량이 많은 문제점 또한 존재한다. 작성하던 코드 중 JOIN을 3개의 테이블에 걸쳐 쿼리를 날려야되는 API가 있었는데 모든 칼럼을 SELECT해올 필요가 없어서 조금 코드 가시성은 떨어져도 .leftJoinAndSelect의 사용을 지양하고, .leftJoin과 .select, .addSelect를 사용하여 작성하였다. async fin..

Article Thumbnail
Duplicate key value violates unique constraint

개발/PostgreSQL 2022. 1. 16. 01:43

포스트를 저장하는 API에서 500번대 에러가 발생하였다. 에러 로그를 찍어보니 "QueryFailedError: dupliacte key value violates unique constraint "PK_eff3e46d24d416b52a7e0ae4159"라고 출력되었다. 원인 TypeORM에서 @Entity를 통해 테이블을 생성하고, id 칼럼을 @PrimarayGeneratedColumn을 사용하여 primary key로 지정하고 unique value로 지정하고 PostgreSQL로 매핑하였는데 데이터를 복사하여 테이블로 이동시키면서 시퀀스 객체와 테이블의 키 값에 차이가 나면서 insert시 Duplicate key value violates unique constraint 에러가 발생된다. 해결..

TypeORM GroupBy를 사용하여 정렬 Count하기

개발/TypeORM 2022. 1. 14. 02:47

모든 유저를 지역별로, 연령별로 정렬하여 유저 수를 통계를 내야되는 이슈가 있었다. 연령별로 묶어서 Count를하여 aged_user: [{age:'21', age_count:'10'}, {age: '22', age_count:'12'}]의 형식으로 프론트에 리턴해주는 것을 목표로 typeorm QueryBuilder를 사용하여 쿼리를 구성하였다. const userByAge = await this.repository .createQueryBuilder('user') // 유저 테이블을 지칭하는 이름을 'user'로 한다. .select('user.age') // 정렬할 유저 테이블의 칼럼만 select한다. .orderBy('user.age', 'DESC') // select한 칼럼을 내림차순으로 정렬..

Article Thumbnail
Date 타입을 유지하면서 전/후 Date 출력하기

개발/TypeScript 2022. 1. 13. 08:20

TypeScript에서 현재 연도월일시분을 가져오는 방법은 아래와 같이 단순하다. const now = new Date(); 현재 기준으로 전날 혹은 다음 달을 포함한 Date를 출력해야되는 경우가 발생하였는데 대부분의 솔루션들은 일 또는 월로 변경시켜서 빼고 더하는 방식으로 Date 타입이 유지가 되지않는다는 단점이 있었다. StackOverflow에서 12년하고도 4달이나 지난 해당 질문에 대한 답변의 대댓글 중에 아래와 같이 처음보는 방식의 코드를 보게되었다. How to subtract days from a plain Date? Is there an easy way of taking a olain JavaScript Date (e.g. today) and going back X days? So, ..

Article Thumbnail
2021년 회고

년도별 회고 2022. 1. 3. 04:06

2021년 1월 1일날 "올해는 꼭 코로나 없어지게 해주세요" 라고 소원 빌었던 게 엊그제 같은데 벌써 2021년의 크리스마스가 지나고, 2022년을 향해 가고 있다. 평소에도 기억력이 단편적으로 기억해내는 수준이라 기억하는 것 보단 기록하는 것을 선호하는데 올해 처음으로 기술 블로그도 새로 정리하는 김에 1년마다 올해 어떻게 지냈는지, 올해 새롭게 배웠던 것을 회고하려한다. 1. 인턴쉽 2021 한 해는 시작부터 개발과 번아웃의 반복이었다. 20학번으로 대학교에 입학했지만, 코로나로 인해 따로 인간 관계를 넓힐 기회도 없었고, 알던 친구들은 다들 군대에 갔거나, 바빠서 연락도 되지 않았다. 지금 다시 생각해보면 공부하기 좋은 시기였던 거 같다. 이때 자바랑 스프링 공부나 해놓을 걸.... 사담이 길었지..

Article Thumbnail
SubScriber afterRemove( )에서 removeEvent의 Entity가 notFound인 이유

개발/TypeORM 2021. 12. 26. 17:14

LikeCount와 같은 테이블의 number 칼럼에 +1 혹은 -1을 할 일이 생기는 경우, +1을 하는 API를 새로 구성하는 것 보다 Like 테이블에 row가 추가될 때마다 SubScriber에서 트랜잭션을 열고, +1을 추가하는 것이 프론트의 api 호출 빈도를 줄일 수 있다는 점에서 장점이 있다고 생각하였다. +1의 경우, TypeORM afterInsert( )를 사용하여 insertEvent가 해당 테이블에서 발생시 number +=1을 하는 방식으로 작성하여, 정상적으로 likeCount 칼럼의 값에 +1이 되는 것을 확인하였는데, -1의 경우, 테이블에서 해당 정보가 삭제되더라도 removeEvent가 row가 삭제된 것을 체크하지않아 -=1이 되지않는 문제가 발생하였다. 원인 Dele..

Article Thumbnail
[TypeORM] SubScriber에서 camel Case 방식 칼럼값 업데이트 시 QueryFailedError: column does not exist 발생 시

개발/TypeORM 2021. 12. 19. 00:25

좋아요 API를 구현하고, 테스트 하던 중 아래와 같이 Column "likecount" does not exist 에러가 발생하였다. 그런데 해당 칼럼은 스토리 테이블에 존재하는 칼럼이다. 아래와 같이 TypeORM의 EntitySubscriberInterface를 implement해서 LikeSubScriber를 구현하였는데 afterInsert와 InsertEvent를 통해 Like 테이블에 새로운 row가 추가될 때마다 Story 테이블의 해당 스토리 likeCount 칼럼에 +=1을 하는 방식으로 해당 이슈를 참고하여 구현하였다. How can I incr/decr a value? · Issue #680 · typeorm/typeorm How can I increase a value by one..

Article Thumbnail
[TypeORM] QueryBuilder의 limit 과 take의 차이

개발/TypeORM 2021. 12. 11. 22:00

CreateQueryBuilder를 사용하여 API를 구성하다가 .leftJoin으로 현재 QueryBuilder가 위치한 Entity외에 다른 JOIN Table에서 정보를 가져와서 필터링을 해야하는 경우가 생겼다. 해당 API 실행 계획은 다음과 같았다. 카테고리 스토리 JOIN 테이블에서 스토리 ID로 카테고리 리스트를 찾은 다음, 카테고리 리스트의 ID로 카테고리 스토리 JOIN 테이블를 조회하여 현재 스토리를 제외한 나머지 스토리 리스트를 전달한다. 위의 실행 계획을 createQueryBuilder에 해당 JOIN테이블을 leftJoin하는 방식으로 구현하였는데 .limit(n)을 추가하면, 쿼리가 고장나서 예상과 다른 쿼리를 2번을 날리고 스토리가 2개만 들어있는 Array가 2번 리턴되는 ..

Article Thumbnail
[TypeORM] SubScriber 활용하여 User Role 변경 감지 알림 보내기

개발/TypeORM 2021. 12. 1. 11:45

어드민이 유저의 등급을 일반 유저에서 Prime 혹은 특별 유저로 변경 시, 해당 유저에게 알림이 가야되는 로직을 TypeORM의 SubScriber를 통해 구현하였다. afterUpdate를 사용하여 유저 테이블에 변경이 생기면 이를 감지하여 알림 테이블에 지정된 알림 데이터를 저장하는 방식으로 하였는데 유저가 유저 정보를 수정해도 해당 afterUpdate가 작동하는 문제가 발생하였다. 이 문제를 해결하기 위해서는 유저 테이블의 변경이 생기기 이전의 정보와 변경 이후의 정보의 특정 칼럼을 활용하여 예외처리를 해야하는데 TypeORM의 공식 Subscriber 문서를 찾아보면 따로 존재하는 것 같지 않았는데 TypeORM 깃헙 이슈에서 event.databaseEntity를 통해 변경이전의 정보를 가져..