ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Node.js & mongoose 컬렉션 히스토리 관리
    프로젝트/개발자 지름길 2021. 11. 30. 21:45
    반응형

    현재 진행중인 프로젝트 '개발자 지름길'에서는 퀴즈 컬렉션을 등록/수정/삭제에 대해서 히스토리를 관리한다.

     

    나는 히스토리 관리를 위해서 데이터 변경이 일어나는지 감지후, 데이터 변경이 발생하면 히스토리를 새롭게 추가하도록 했다. 이를 위해서 EventEmitter를 이용했다.

     

    그 방법은 아래처럼 코드를 작성하면 특정 'TargetModel'에 대한 change 이벤트를 감지할 수 있다. 신규 입력 시에는 change.operationType 값이 'insert'이며, 수정 시에는 'update'가 나타난다. 이 방법은 mongoose 데이터 저장 함수 save, findAndUpdate, updateMany 등 여러 함수들을 모두 감지할 수 있는 방법이다.

     

    사실 기능은 insert와 update 외에도 더 많이 있다. 자세한 내용은 아래 첫 번째 링크를 확인해보기를 바란다. 

     

    참고 :

    https://docs.mongodb.com/manual/reference/change-events/

    https://stackoverflow.com/questions/48269827/mongoose-how-to-listen-for-collection-changes

    const EventEmitter = TargetModel.watch()
    
    EventEmitter.on('change', change => {
    	console.log(JSON.stringify(change))
        
        if(change.operationType === 'insert'){
    		// 신규
    	}
        else if(change.operationType === 'update'){
    		// 수정
    	}
    })

     

    처음에는 내가 고려했던 방법은 3가지가 있다.

    1. 데이터 CUD 전에 mongoose hooks에서 pre나 post를 활용하여 history를 관리하는 방법.

    2. 데이터 CUD 로직에 직접적으로 히스토리 남기는 로직 추가.

    3. 라이브러리 활용

     

    그런데 위에 있는 3가지 모두 활용하지 않고, 더 많이 검색하다보니 이벤트를 감지할 수 있음을 알게되었다. 그래서 이벤트 감지하여 데이터를 처리하는 방법으로 진행했다. 이 방법이 서버 성능을 저하시킨다거나 실제 활용할 때 문제가 되는지는 잘 모르겠다. 충분한 검증이 필요할 것으로 예상된다. 아직은 개발 단계이기 때문에 이벤트 감지하여 처리하는 방법으로 개발 후, 서버 오픈을 하고자 한다. 서버 오픈 후에 문제가 된다면, 제거후 새롭게 개발하면 되지 않을까?... 나는 여튼 그렇게 생각했다.

     

    위에 있는 3가지 방법을 활용하지 않은 이유는 다음과 같다.

    1. 데이터 CUD 전에 mongoose hooks에서 pre나 post를 활용하여 history를 관리하는 방법.

    => 데이터 CUD 하는 방법은 여러 가지가 있다. create, save, findAndUpdate findOneAndUpdate, ... 처럼 말이다. 내가 모르는 함수들도 더 있을거다. 이 모든 상황들에 대해서 하나하나 다 설정하기는 힘들거 같았다. 혹시나 누락된 부분이 있을 수도 있는거다. 내가 만약에 누군가와 협업을 하거나 내 코드가 누군가에게 보여진다면 이 방법을 채택하면 안될거 같았다.

     

    2. 데이터 CUD 로직에 직접적으로 히스토리 남기는 로직 추가

    => 데이터 CUD 전후에 항상 히스토리를 기록하는 방법이 일반적으로 많이 사용된다. 하지만, 나는 실제로 유지보수 업무를 하면서 신입 때, 특정 테이블에 대해서 히스토리 관리가 되고 있는지 전혀 몰랐다. 그래서 히스토리 추가하는 로직이 누락되기도 했다. 내가 지금 작성하고 있는 코드를 나중에 다시 작성할 때, 해당 컬렉션(테이블)에 대해서 히스토리 관리하는지 자세하게 기억하고 있을지는 모른다. 그래서 분명 언젠가 누락되는 소스코드가 발생할 수도 있다고 생각했다. 그래서 해당 방법을 채택하지 않았다.

     

    3. 라이브러리 활용

    => 라이브러리 주간 다운로드 횟수를 보면 그렇게 아래 이미지처럼 써야할 이유가 느껴지지 않는다. 그래서 활용하지 않았다. 

     

     

     

    내 식견이 좁아서 이 정도 고민만 하고 내 마음대로 코드를 작성한거는 맞다. 이렇게 히스토리 관리하는 부분에 대해서 구글링 해도 내가 잘 찾지를 못하겠더라... 그래서 적당히 괜찮은 소스코드를 작성하고자 마음 먹었다. 그리하여 개발한게 모델 change 이벤트가 발생하면 데이터를 처리하는 방법으로 개발을 진행했다.

     

    이렇게 개발하면 장점은 이렇다.

    특정 기능을 개발하거나 유지보수 하더라도 히스토리 컬렉션(테이블)에 대해서는 전혀 신경쓰지 않아도 된다. 그러므로 인적장애가 발생할 가능성이 낮아진다.

     

    단점은 이렇다.

    1. 히스토리에 대한 로직을 순서대로 따라가면서 디버깅하기 어려울 수 있다. 처음 보는 사람에게 있어서 해당 소스코드는 충분히 의문이 생길 수 있다. 그러니 이 부분에 대해서 로직에 대한 문서를 만들어 놓으면 좋을거 같다.

    2. 컬렉션 컬럼이 변경될 경우에 히스토리에 대한 로직이 어떠한 문제가 생길지는 모른다. 그러나 이 문제에 대해서는 기존에 내가 고려했던 1번 방법과 2번 방법 역시 마찬가지다.

     

    결론 : 

    성능에 문제만 없다면, 현재 내가 생각한 로직이 나름 괜찮을지도?

    현재 히스토리 관리하는게 하나 뿐이지만, 추후에 조금 더 서비스가 커진다면 다른 컬렉션에 대해서 히스토리 관리를 할 수 있도록 할 예정이다. 그러니 추후 확장성을 고려해서 폴더구조를 작성하자.

     

     

     

     

    반응형

    댓글

Designed by Tistory.