always 반환 타입: a -> b -> a 언제나 동일한 값을 반환한다. const라고 다른 언어에서 알려져 있다. [1,2,3,4].map(always(0)) => [0,0,0,0] curry 반환 타입: (fn: (...args: TArgs) => TReturn): CurriedFn 여러 인자를 받는 함수의 커리 버전이다. 타입스크립트에서 타입 유추가 가능하다. const sum3 = ( x: number, y: number, z: number ) => x + y + z const curriedSum3 = curry(sum3) === curriedSum3(1) // (y: number, z: number) => number curriedSum3(1, 2) // (z: number) => numbe..
참고 문서 --- Either는 Left와 Right 두 방향으로 구성된 데이터 타입이다. Maybe와 유사하나 누락된 값에 대한 정보 저장이 가능하다는 특징이 있다(가령 에러 메시지 같은). "Right is right" 라는 컨벤션이 있어 대개 성공값은 Right에, 실패값은 Left에 저장한다. 오른쪽 편향적이므로 map, chain과 유사한 메소드들은 Right에서 동작한다. Left 일반적으로 동작에 대한 실패를 나타내는 정보를 담당한다.// Inferred type is randomEither: () => Either | Either const randomEither = () => Math.random() > 0.5 ? Right(1) : Left('Error')Left('..
기초 Maybe는 데이터 타입으로 함수의 근본적 오류와 결측값 표시(???)에 사용된다. 값일 수도(Just) 있고 아무것도 아닐 수도(Nothing) 있다. Just는 현재의 값을 래핑하는 객체이다. Nothing은 부재의 값을 의미한다. 단순히 null이라고 해석해도 좋다. 두 값은 모두 null 체크가 되지 않은 옵셔널한 값이나 익셉션 핸들링을 다루기 쉽게 돕는다. 사용하지 않은 경우 const port = parseInt(getConfig()?.port ?? '8080'사용한 경우 const port = getConfig() .chain(x => x.port) .map(parseInt) .orDefault(8080) 메소드의 종류 of 타입: Maybe Just 타입으로 래핑된 값을..
Jest의 설정 파일은 package.json에 있다. 우선 config에 verbose: true 설정을 줘야 console과 같은 자세한 로그 확인이 가능하다. 그리고 jest는 src를 읽지 못하는데, 그리고 jest에서 rootDir를 src로 쓸려면 moduleNameMapper를 jest config에서 설정해줘야한다. { "jest": { ... "verbose": true, "moduleNameMapper": { "^src/(.*)$": "/$1" } } }
오늘은 Nest.js를 사용해 대표적인 양방향 암호화 방식인 AES를 적용해 볼 것이다. 사용하는 모듈은 crypto이다. AES가 뭐지? 일반적으로 개발에서 가장 많이 사용되는 암호화는 단방향 암호화인 hash이다. 비밀번호 저장 등 중요한 사용자의 정보를 보관할 때 쓰이며, 이때 사용자의 정보는 compare를 통한 비교만 가능할 뿐, 원본값을 찾아내는 것은 어렵다. 복호화가 불가능한 것이다. 반면 AES는 양방향 암호화에 해당하며, 보내는 쪽과 받는 쪽 모두 key를 가지고 있으면 원래의 값을 추출해내는 것이 가능하다. 자세한 설명은 여기에서 볼 수 있다. 어디에 쓰길래? 사용자의 정보값을 기준으로 동작해야하는 api가 최근 개발되어야하는데, 사용자의 정보값은 마스킹이 되어야하는 값이다. 그러므로 ..
최근 사이드 프로젝트를 하다가 이런 오류가 발생했다. const friendEntityList = await this.friendRepository.find({ where: { refUserUid: 1 } }) 다음과 같이 코드를 작성하자 DeepPartial 타입과 number 타입은 호환이 되지 않는다면서 기존 코드에서 모두 오류를 반환한 것이다. 근데 제일 먼저 든 생각은 (어...? 이상하다 나 이거 회사에서 맨날 이렇게 썼었는데...??) 였다. 알고 보니 회사의 typeORM은 0.2 버전대였고 내가 이번에 설치한 typeORM은 0.3버전대였던 것이다... 다음 문서에서 changelog를 확인할 수 있다. Equal이라는 객체가 새로 생기게 되었으므로, 다음과 같이 쓰면 된다. const ..
최근 서버에서 redis 관련한 이슈가 몇번 나왔었다. 우리 서비스의 redis는 사내의 쿠브플로우 온프레미스 서버에 레플리카셋으로 올라가있는데(sentinel은 안 쓰는 상태), 개발 api 서버에서는 strict하게 master의 url만 사용했다. 이 때문에 인터넷이 끊기는 등 redis에 이상이 생겨서 기존 master가 slave로 전향해버리면 set이나 incr, expire 등의 명령어가 적용되지 않았다. 일반적으로 slave replica는 readonly 상태이므로 삽입이 불가능하기 때문이다. 때문에 프로덕션 환경 redis에 sentinel이 적용되었고, 개인 로컬 환경도 sentinel을 사용할 필요성이 생겼다. local 환경은 대충 가볍게 써서 이런 정도만 나오게 되었다. glob..
테스트 개요 테스트는 크게 3개로 나뉩니다. 개별적인 로직을 검증하는 유닛 테스트와, 실 사용자가 수행하는 시나리오대로 흘러가는 것을 검증하는 E2E 테스트, 모듈 간의 호환성과 통합 과정을 검증하는 통합 테스트 등입니다. 개중에서도 유닛 테스트를, 특히 TestContainer를 기반으로 작성한 이야기를 해보려고 합니다. 유닛 테스트는 각 기능 단위에서 수행하는 로직이 무결함을 보여주는 것이 주된 목표입니다. 때문에 의존성이나 다른 코드에 의한 변동이 발생해서는 안됩니다. 가령, 가입한 사용자를 검증하는 로직을 테스트할 때, 다른 로직에서 회원가입을 진행하여 DB에 동일한 ID의 사용자가 있으면 테스트가 실패할 수 있습니다. 만일 중복 가입에 대한 테스트를 하고자 했던 것이 아니라면, 이는 올바른 테스..