일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- 자바스크립트
- Nestjs
- HTTP 완벽 가이드
- typescript
- 백준
- 수학
- javascript
- 레벨 1
- Algorithm
- 문자열
- 소켓
- 그래프
- dp
- Crawling
- socket
- 크롤링
- 가천대
- 타입 챌린지
- 쉬운 문제
- BFS
- ip
- type challenge
- 프로그래머스 레벨 2
- 프로그래머스
- dfs
- HTTP
- 타입스크립트
- 알고리즘
- Node.js
- TCP
- Today
- Total
목록프로그래밍/NestJS (38)
kakasoo
import { SchemaObject } from '@nestjs/swagger/dist/interfaces/open-api-spec.interface'; export const ERROR = { ALREADY_CREATED_EMAIL: { code: 4001, message: '이미 생성된 이메일입니다.' }, NO_AUTH_TOKEN: { code: 4002, message: '인증이 필요합니다.' }, IS_SAME_POSITION: { code: 4003, message: '이미지의 정렬 값이 동일한 경우가 존재합니다.' }, } as const; type KeyOfError = keyof typeof ERROR; type ValueOfError = (typeof ERROR)[KeyOfError..
import { BadRequestException, ExecutionContext, Injectable } from '@nestjs/common'; import { AuthGuard } from '@nestjs/passport'; import { ERROR } from '@root/config/constant/error'; import { DecodedUserToken } from '@root/types'; @Injectable() export class JwtGuard extends AuthGuard('jwt') { handleRequest( err: any, user: any, info: any, context: ExecutionContext, status?: any, ): TUser { if (i..
// package.json의 일부 { "dependencies": { "@nestjs/common": "^9.2.1", "@nestjs/testing": "^9.2.1", "typescript": "^4.9.4" }, "devDependencies": { "@types/jest": "^29.2.5", "@types/node": "^18.11.18", "jest": "^29.3.1", "ts-jest": "^29.0.3" }, } 최소한의 라이브러리로 위와 같이 install을 진행했다. NestJS 라이브러리를 만들 것이기 때문에 @nestjs/common과 @nestjs/testing을 install 하였고, typescript를 쓰기 위해 typescript library와 각종 타입, 테스트를 위..
구글에는 googleapis 라는 라이브러리 (* 아래 링크) 도 있지만 사용하지 않는 것이 좋다. googleapis 이 라이브러리의 경우 구글에서 제공하는 모든 API가 다 들어 있기 때문에 어플리케이션에서 쓰기엔 버겁다. 용량 자체가 120MB 정도가 되는데 서버 성능이 부족하면, 예를 들어 EC2가 t3.micro, small 급이라면, 그런 경우에는 서버를 빌드할 때 JavaScript의 Heap memory가 부족하다는 오류를 내뱉으며 멈추게 된다. 그렇기 때문에 만약, 스프레드시트를 생성한다. 데이터를 넣는다. 그 시트를 구글 드라이브를 이용해 다른 사람에게 공유한다. 와 같이, 스프레드시트 이후에 연계될 다음 동작들이 있지 않다면 npm에서 적절한 라이브러리를 찾는 게 낫다. 여기서 말하는..
@IsDate() specificDate: Date; 날짜를 검증하기 위해서는 IsDate 데코레이터를 이용할 수 있다. 이렇게 작성할 경우 단순 String으로 된 Date는 무시당할 수 있기 때문에 Type 데코레이터도 필요하다. 날짜가 필수적인지 아닌지에 따라 아래와 같이 작성할 수 있다. import { applyDecorators } from '@nestjs/common'; import { Type } from 'class-transformer'; import { IsDate, IsNotEmpty } from 'class-validator'; export function IsNotEmptyDate() { return applyDecorators( IsNotEmpty(), IsDate(), Typ..
[Postgresql] TO_CHAR로 날짜 다루기 this.repository .createQueryBuilder('qb') .where(`TO_CHAR(qb.createAt, 'yyyy-mm') = TO_CHAR(CURRENT_DATE, 'yyyy-mm')`) .getMany(); 특정 날짜의 데이터를 뽑기 위해서는 일반적으로 검색 기간의 시작 날짜와 끝 날짜를 이용해 조회한다. 그래서 where문에 MoreThan, MoreThanEqual, LessThan, LessThanEqual, Between 을 사용한다. 다만 이 방식으로는 DB에서 사용 중인 시간 대에 맞게, 클라이언트, 서버, DB 간 시간 대를 맞춰주어야 한다. 서버에서 DB 시간을 맞추든, 아니면 값을 일일히 변환해주든, 변환 과정..
Response DTO를 이용한 응답 직렬화 (Serialization) 초기 기능 개발에는 서비스 로직으로 Response의 형태를 가공해서 제공해주곤 했다. 하지만 기능이 추가됨에 따라, 서비스는 유저 서비스와 판매자 서비스 등, 역할에 따라 모듈이 분리되기 시작했고, 모듈마다 동일한 형태의 데이터를 다루게 될 때마다, 서로 다른 모듈의 서비스를, 데이터 형태 가공 용으로 호출해도 되는지 의문이 됐다. 따라서, 서비스 로직 외에 응답 형태만을 가공하기 위한 레이어가 필요하다는 생각에 다다랐는데, 이 결론이 직렬화였다. 1. class-transformer와 글로벌 인터셉터 npm install reflect-metadata class-transformer reflect-metadata는 코드에 메타 ..
const users = this.userRepository.createQueryBuilder('u') .addOrderBy('u.height', 'DESC', 'NULLS LAST') .getMany(); orderBy의 세번째 파라미터로 NULLS LAST, NULLS FIRST를 지정해서 처리할 수 있다.
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/EkNnW/btrLSvfHWts/jyLPdYK108gPKjcZWMIp51/img.png)
TypeORM에는 setFindOptions 라는 메서드가 있고, 이걸 활용하면 할 수 있는 일이 참 많습니다. 하지만 공식문서에는 이 메서드에 대한 소개가 전혀 없는데요, 이건 TypeORM이 반성해야 할 부분 같습니다. 이 메서드는, QueryBuilder가 가진 문제점을 부분적이나마 해소해줍니다. 코드를 통해 보겠습니다. QueryBuilder 사용법 const posts = await connection .createQueryBuilder(Post, "post") .where('post.author IS NULL') .orderBy("post.id", "ASC") .getMany() post를 조회할 때 우리는 where문과 order를 where, orderBy라는 메서드를 통해 해결할 수 있습..
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/oVhTs/btrLTVkUi1U/q2wbHNQlTjNHJjjvwkCeH0/img.png)
원래 Repository에서 조인 대상에 대해 IsNull로 체크하는 것은 자잘한 버그들이 있었습니다. IsNull로 할 경우, 사용자가 기대하던 방식대로 동작하지 않았는데, 이게 버그인지 의도인지는 알 수 없었습니다. 그래서 이런 경우는, 차라리 쿼리빌더에서 InnerJoin을 하는 것이 낫다는 판단이었습니다. 어떤 식으로 동작할지 명확한 것이 차라리 낫다는 판단이었습니다. 그러고 나서 몇 달의 시간이 지나니 새로운 업데이트가 나왔습니다. 새 업데이트 내용을 보니, 기존의 코드가 의도된 게 아니라 버그였음을 확인할 수 있겠네요. 이 내용은 issue number #8890에 있는 코드를 그대로 옮겨, 해석을 달은 것입니다. 일단 기존에 코드가 어떤 문제가 있었는지, 예제 코드를 통해 이해해보겠습니다. ..
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/5mH5D/btrLOfEKx7t/d0WFmo3qXaet5hT3dX5IK0/img.png)
issue number #8524에서 JoinColumn에서의 제약 조건 이름을 추가하는 법이 추가되었습니다. 이 내용은, 기존의 방식처럼 Entity 위에 @index() 데코레이터를 통해 제약조건을 거는 것보다 명시적입니다. 인덱스 데코레이터의 경우에는 하나의 데코레이터를 이용해 Primary와 복합키, 외래키 등을 모두 표현했습니다. 따라서 그 의미가 무엇을 뜻하는지는 인덱스 데코레이터와 엔티티 칼럼과의 관계를 보고 이해해야 했습니다. issue number #8900에서는 위의 변화와 더불어 Column 데코레이터에서도 제약조건 명시를 허용했습니다. 새로이 명시된 방법은 아래와 같습니다. @Entity() export class Post { @ManyToOne((type) => Category) ..
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/bs355q/btrHrMNiTOB/ZaIYf6YQzL9Fm6KH0QKCkK/img.png)
차근차근 Nest에 대해서 설명하고자 한다. 이 글에서는 Controller와 Service, Repository를 어떻게 구분하면 좋을지를 설명한다. 당연히 각 역할대로 구분하면 된다는, 간단한 소개가 되겠지만, 그 각 역할이 뭔지 이야기 해보자. Module @Module({ imports: [OtherModule], controllers: [SomeController], providers: [SomeService], exports : [SomeService], }) export class SomeModule {} Express 유저라면 처음 Nest를 접하고 나서 이해되지 않는 내부 동작에 놀랄 것이다. 너무 친절한 나머지 개발자가 이해해야 할 부분까지 다 알아서 해버리니 말이다. 그래서 아무렇게나..