서론1부는 이론편, 2부는 실습편입니다.트랜잭션을 통해 테스트 격리성을 가져가고 싶었습니다.단, TypeORM에는 세션을 관리해주지 않아, 하나의 테스트만 실행해도 여러개의 세션이 연결됩니다.위 제약사항에 대한 접근방식 + 해결방법을 공유하겠습니다. 트랜잭션으로 테스트 격리성을 확보한다는게 무슨말이야?각 테스트 간의 영향을 끼치지 않도록 하는 테스트 방법입니다. 크게 두가지 전략이 있습니다.트랜잭션 전략: 테스트 시작과 끝에 트랜잭션을 시작하고 롤백하는 전략클린업 전략: 테스트 종료 후 DB의 모든 행을 제거하는 전략 둘다 처음 들어본다면 향로님의 재미있는 글이 있으니 추천드립니다. (테스트 데이터 초기화에 @Transactional 사용하는 것에 대한 생각, 향로, 2023. 11. 26.)befor..
프로젝트 소개 및 요구사항 waktaverse games라는 약 30개의 팬게임과 협업하는 게임 포럼/배포 서비스입니다. 왁타버스 게임즈 | Waktaverse GamesWaktaverse Games를 통해 왁물원의 게임을 한곳에서 즐겨보세요!waktaverse.games 본 웹 사이트에는 2가지 클라이언트가 존재합니다.웹 브라우저(react)팬게임 개발자용 클라이언트(electron)각 클라이언트마다 고유의 refresh 토큰을 가지고 있어서 메서드 내부에서 처리해줘야 하는 중복 로직이 많았습니다.그래서 이번 글에서는 다음과 같은 작업을 수행해보겠습니다.클라이언트가 더 추가되도 코드의 변경이 일어나지 않도록 개선request query에 따라 service가 동적으로 할당되도록 개선 Service 동..
서론 난 왜 이걸 하고 있는가? 현재 교수님이 속해 있는 회사의 렌딩페이지를 급하게 만들어야 했습니다. html5up이라는 html 예제 모음 사이트에서 가져와서 내부 콘텐츠만 변경하여 작업하기로 결정하였습니다. 다운받은 예제는 외부 라이브러리 없이 html, css, js만으로 구현되어 있습니다. 이를 추후 간편한 수정을 위해 React로 마이그레이션을 진행해야만 했습니다. 무슨 문제에 봉착했는가? 다운받은 템플릿(live demo)에 속해있는 js 기능이 정상적으로 동작하지 않았습니다. React에 포함되어 있는 /public/index.html의 body 태그 내 마지막 줄에 js를 불러오는 script 태그를 추가했지만 실패했습니다. 본론 작업에 실패했던 이유 React의 동작 방식에 대한 이해 ..
로컬 환경에서 ibd 파일을 이용하여 데이터를 복구하려고 했습니다. 일부 테이블이 스키마 불일치 문제로 복구되지 않아서 바이너리 로그로 복구를 진행해봤습니다.혹시 저처럼 DB를 날려버리신 분들을 위해 제 삽질과 더 빠른 DB 복구를 위한 본 글을 작성합니다. 도움이 되었으면 좋겠습니다. 이해하기MySQL에는 바이너리 로그라는 파일이 존재합니다. 사용자가 사용했던 쿼리들이 기록되어 있는 파일입니다. (SELECT는 예외)DB 생성 시부터 binlog.000001으로 매일 binlog 파일이 생성되며 1씩 증가합니다.MySQL에 설정되어 있는 binlog 보존 기간만큼만 저장되다, 보존 기간을 초과한 파일은 삭제됩니다. 때문에 binlog 파일이 1부터 시작하지 않는다면.. 이미 옛 binlog 파일들은 삭..
혹시 저처럼 DB를 날려버리신 분들을 위해 제 삽질과 더 빠른 DB 복구를 위한 본 글을 작성합니다. 도움이 되었으면 좋겠습니다. 이해하기데이터 복구를 시작하기 전에 복구에 필요한 데이터를 설명드리겠습니다..ibd 파일: 각 테이블의 데이터가 저장된 파일(InnoDB)MySQL: ibd파일을 생성했던 MySQL 동일한 버전의 MySQL(완전히 동일해야 합니다.).frm 파일: 각 테이블의 스키마가 저장된 파일(8.0 버전부터 삭제됨).ibd파일은/var/lib/mysql/{database_name}/{table}.idb 이런 경로로 존재합니다. 데이터베이스 구동 환경 구축삽질을 하며 시간이 DB 구축과 삭제를 너무 많이 하게 되어서 docker-compose.yml으로 환경을 구축하였습니다. # dock..
서론. 기존 git pull && yarn build && yarn run으로만 관리하던 프로젝트의 메모리가 꽉찼다. 아래는 프로젝트 관련 파일을 다 삭제한 상태.. 그래도 8%의 여유공간밖에 없다. 문제 인식: 어째서 프로젝트가 이 모양이 되었는가? ec2 8GB 1 인스턴스를 사용하고 있다. (t2.micro) 우리 프로젝트는 크롬 드라이버를 활용하여 크롤링을 진행하는데 크롬 드라이버가 용량을 많이 차지하는 것이 의심된다. 크롬 브라우저, 크롬 드라이버를 설치하고, 여러 라이브러리(git, npm etc)들에 의존하기 때문에 설치한 라이브러리들이 굉장히 많다. 아마도 같이 설치되고 삭제되지 않은 데이터들이 숨어있는 것이 문제일 것이다. 해결 방안: 어떻게 해결할 것인가? 우선, 메모리를 늘리는 것은 ..
개요 리프레시 토큰을 Redis에 저장한다는 사례를 들어서 직접 구현해봤습니다. Token Based Authenticaion, Refresh Token을 공부해보았습니다. 결론: 해당 방식은 비효율적이고 보안적 가치가 없는 방식이었습니다. What is Redis? 레디스는 인메모리 방식의 데이터베이스입니다. Diff Basic DB vs In-Memory DB 기존 DB(e.g. mysql, postgreSQL)은 보조기억장치에 데이터를 저장합니다. 그래서 많은 양의 데이터를 오래 저장하는 데에 적절합니다. 인메모리 DB(e.g. Redis, MemCache)는 주기억장치에 데이터를 저장합니다. 그렇기에 데이터 조회 성능이 월등히 빠릅니다. 주기억장치를 이용하기 때문에 RAM의 휘발성 메모리의 특징도..
서론 학교 백엔드 CS 스터디 중 카디널리티라는 키워드가 나왔습니다. 설명 들었을 때 처음듣는데 중요하다고 생각되어 조사해보고 정리해본 후, 개발했던 프로젝트 리팩토링을 진행하였습니다. 카디널리티(cardinality)이란? 우리 레코드를 조회할 때 인덱스를 정의합니다. 인덱스를 정의할 때 우리는 카디널리티가 높은 것을 사용합니다. 카디널리티란? 해당 컬럼의 중복된 수치를 말합니다. "성별, 학년, 국적 등은 카디널리티가 낮다"라고 말하며, 반대로 "학번, 주민등록번호 등은 카디널리티가 높다"라고 말합니다. 우리가 성별, 학년같은걸 인덱스로 잡진 않죠? 그렇다면 복합키(여러 컬럼을 인덱스로 구성)를 사용한다면 어떻게 될까요? 우선, 복합키의 예시를 가져와보겠습니다. 위 이미지의 user-auths 테이블..
팀원이 설정/수정한 알림이 내 폰에서 울려야한다. 서론 프로젝트를 전부 구현해놨더니 기획을 엎어버렸다. 내가 기획팀한테 타 서비스와의 차별성과 방향성이 애매하다고 하긴했지만, 이런 결과를 원한 것은 아니다.. ㅠㅠ 지인들은 기획팀을 엎으라고 했지만, 더 나은 결과물을 위한 것이니 좋게 생각하고 있다. 개선된 기획안은 이렇다. "열정은 있지만 팀프로젝트를 할 사람이 필요한 사람들에게 마음맞는 팀원을 구할 수 있는 TODO 및 캘린더 기능과 커뮤니티를 제공해준다." 여기서 TODO, 캘린더 기능이 팀 단위로도 설정할 수 있기 때문에 본인이 아닌 다른 팀원이 추가, 수정한 알람이 내 폰에서 울려야한다. 본론 FCM쓰면 되긴하는데 학생이니 구현 경험을 쌓고 싶었다.. 내가 조사해본 결과 우리 프로젝트에 가장 ..
https://github.com/inje-megabrain/waka-board-be GitHub - inje-megabrain/waka-board-be Contribute to inje-megabrain/waka-board-be development by creating an account on GitHub. github.com 이번 게시글에서 쓰일 프로젝트다. 프로젝트 요구 사항은 아래와 같다. 동아리 WAKATIME 관리 프로젝트이다. 테이블에는 코딩 시간이 저장된다. (20분마다 갱신됨) 조회하는 케이스는 둘이다. 오늘 코딩 시간 조회 지난 n일전에 얼마나 코딩했는데 조회 및 평균 계산 로그를 id로 직접 조회할 일은 없다. DB 설계 테이블 소개 user: wakatime 이용자의 계정 정보를 ..
OAuth 로그인을 하는데 새로운 계정이 생성되면 안된다. 서론 애플리케이션 프로젝트 기획 회의에서 회원의 로그인 방식에 대해 이야기했다. 우리 애플리케이션은 회원간의 팀 활동을 통해 함께 성장할 수 있는 커뮤니티 애플리케이션이다. 로그인 방식을 개발하며 기획 개선사항이 있어 이를 기획 팀에 건의했다. 우선, 현재 기획에서의 로그인 방식은 이렇다. OAuth2 인증을 통해 카카오,네이버, 구글, 애플 로그인 등을 제공하기로 하였다. 여기서 백엔드 개발자가 설계할 수 있는 방향은 크게 2가지다. 새로운 OAuth 로그인 시, 새로운 계정으로 회원가입되도록 설계 새로운 OAuth 로그인 시, 이전에 가입한 계정으로 로그인되도록 설계 2번 방식이 애플리케이션 기획과 UX를 해치지 않을 것이라고 생각하여, 2번..
await/ async에 대한 문법 소개 글을 작성하다가 기초가 부족해서 이 질문까지 왔다. await / async 설명 작성 중.. → “아.. 이걸 설명하려니까 Promise를 배워야겠다.” → “어 Promise를 보면 비동기 처리가 가능하다고 하는데 자바스크립트는 싱글스레드가 아닌가?“ → “Node.js는 다른가? Node.js는 JS의 단순 런타임이 아닌가?” JS가 싱글 스레드인데 어떻게 비동기 처리가 가능한지 학생 분들이 계신 방에 질문해봤다. → 저학년들이 많고, Node 진형 개발자분들이 적어 스레드 풀 얘기까지는 나왔지만, 제대로 된 답이 나오지 않았다. 현직자 분들이 많은 개발바닥 채팅방에 질문해봤다. → Node.js에 포함된 libuv라는 라이브러리가 비동기 처리를 책임져준다...
서론 온라인 인기글, 핫한 주제등을 한 눈에 보여줌으로 통하여 영감을 제공하는 사이트를 개발하고 있다. 다시 말해서 종합 크롤러 사이트인데, 우리 서비스에서 사용하는 크롤러들을 관리할 수 있는 페이지를 개발하였다. 여기서 사용한 라이브러리가 AdminJS이다. Nest.js에서 사용할 수 있는 Admin 라이브러리는 3가지다. Admin Bro (Beta) AdminJS NestJs Admin 선택 및 비선택 사유 Admin Bro: Admin Bro는 Beta 버전이라고 적혀있어서 패스했다. 다만, 개발을 진행해보면서 많은 깃헙 레퍼지토리를 확인해보니 Admin Bro를 이용하여 개발한 프로젝트도 꽤나 있었고, 개발 커뮤니티에서 질문글도 많았으며, 무엇보다 AdminJS와 같은 사에서 만들어서 거의 유..
서론 NESTJS에서 커뮤니티 크롤러를 만들던 중 용량이 큰 자료가 많은 스압(스크롤 압박) 글들 때문에 크롤러가 Timeout Error가 뜨는 일이 발생했다. 생각해보니, 불필요한 이미지는 수신할 필요가 없었다. JS 크롤러 라이브러리인 puppeteer을 이용해서 효율적으로 크롤링을 진행해보려고 한다. 사용 스택 Nest.JS 9 // 무관 es2017 puppeteer 19.4.1 (준비하기..) 혹시 설치도 안되어있다면 설치하자.. yarn add puppeteer 공식 문서 설치 관련 페이지 시작하기 import * as puppeteer from 'puppeteer'; const browser = await puppeteer.launch({ headless: false }); const pa..