깊은바다거북
개발 공부 기록
깊은바다거북
전체 방문자
오늘
어제
  • 분류 전체보기 (219)
    • JAVA (9)
    • JavaScript (15)
    • 스파르타코딩클럽 (11)
      • [내일배움단] 웹개발 종합반 개발일지 (5)
      • [내일배움캠프] 프로젝트와 트러블 슈팅 (6)
    • SQL | NoSQL (4)
    • CS 등등 (0)
    • TIL | WIL (173)
    • 기타 에러 해결 (3)
    • 내 살 길 궁리 (4)

인기 글

최근 글

최근 댓글

태그

  • leetcode-cli
  • 혼자 공부하는 자바스크립트
  • 시간 복잡도
  • 팀 프로젝트
  • Inorder Traversal(중위 순회)
  • Backtracking(백트래킹)
  • 재귀 함수
  • Leetcode
  • 자료 구조
  • TIT (Today I Troubleshot)
  • Til
  • 최대 힙(Max Heap)
  • 트러블 슈팅 Troubleshooting
  • DFS(깊이우선탐색)
  • Linked List
  • 코딩테스트 연습문제
  • Binary Tree(이진 트리)
  • tree
  • BFS(너비우선탐색)
  • 자잘한 에러 해결
  • POST / GET 요청
  • Preorder Traversal(전위 순회)
  • 자바스크립트 기초 문법
  • 점화식(Recurrence Relation)
  • 최소 힙(Min Heap)
  • 프로그래머스
  • 01. 미니 프로젝트
  • Trie
  • BST(이진 탐색 트리)
  • TypeScript
hELLO · Designed By 정상우.
깊은바다거북

개발 공부 기록

TIL | WIL

2/3 금 (merge 충돌 해결, 충돌 해결) TIL

2023. 2. 3. 23:50

(베이커리 이커머스 프로젝트 3일차)

깃헙 develop 브랜치와 팀원들 feature 브랜치 사이의 간극이 벌어지지 않게 하려고 노력중. 와중에 발생한 무수히 많은 병합 충돌을 처리하며 브랜치 사이의 ‘간극’에 점점 더 치를 떨게 됨. 머지않아 풀 리퀘스트 빌런, PR 무새가 될 것 같다.

…저기, 깃헙 본인 브랜치에 푸시 해주신 건 좋아요..! 이제 PR도 해주세요. 겁먹지 마세요 PR만으로는 문제가 되지 않아요 충돌 해결하는 리뷰어만 힘을 내면 됩니다..! pull 자주 받아주셔서 감사합니다. 본인 코드도 자주 풀 리퀘 해주세요… 허허 저희 언제 한 번 다같이 화면 켜두고 풀 → 풀 리퀘 사이클 한 번 돌아볼까요.

오늘 한 일

  • ejs 템플릿 구조 분석을 마쳤다.
  • nodemon과 Joi를 API 테스트에 활용함.

    ⇒ 수정할 때마다 서버 재실행하고 Postman으로 일일이 버튼 클릭해서 쓰던 때보다 너무나 편리하다.

    // package.json
    "scripts": {
      "start": "nodemon app.js"
    },
    // nodemon.json 설정파일 없이 그냥 이걸로 충분한가? => 충분하다
    // api.rest 예시
    GET http://localhost:7000/products
    
    ###
    
    POST http://localhost:7000/products/admin
    Content-Type: application/json
    
    {
      "product_name": "Chocolate Cup Cake",
      "product_price": "3200",
      "product_detail": "촉촉한 초코 컵케익",
      "product_image": "public/img/super-moist-chocolate-cupcakes-524176-1.jpg"
    }
    
    ###
  • ‘상품’ CRUD 완성함.

빵 이미지 출처:

https://www.breadtop.com.au/

https://labaking.com/#!products/desserts/29/black-forest/

이미지 저장하는 방법들

sdk s3 bucket

multer

내일 할 일:

  • order 테이블에 ‘status’ 필드를 추가해야 할지 고민해보기
  • 프론트 구현
  • (옵션)회원가입/로그인 기능 살펴보기
  • admin 미들웨어에서 곧바로 DB 모델을 호출하는 것이 괜찮은가?
  • (옵션)테스트에 Joi 활용을 고민중.

(앞으로 사용하게 될 docs들)

express-ejs-layouts 모듈 사용법 - https://www.npmjs.com/package/express-ejs-layouts

sequelize (구체적) api 문서 - https://sequelize.org/v3/api/model/

express.js res.render()와 그 외 문서 - https://www.geeksforgeeks.org/express-js-res-render-function/


어느 계층에서 발생한 에러인가 - error.stack

  • 다음과 같이 컨트롤러 계층에서:
    // controllers/user.controller.js
    findUserInfo = async (req, res) => {
      // const { user_id } = req.locals.user;
      const user_id = 4;
      try {
        const user = await this.UserService.findUserInfo(user_id);
        return res.status(200).json({
          user,
        });
      } catch (e) {
        return res.json({
          error: e,
          errorMessage: e.message,
          errorStack: e.stack,
        });
      }
    };
  • 서비스 계층에서:
    // services/user.service.js
    findUserInfo = async (user_id) => {
      try {
        const user = await this.UserRepository.findUserInfo(user_id);
        return user;
      } catch (e) {
        e.name = 'service layer error';
        e.message = '서비스 계층에서 문제 발생.';
        e.status = 500;
        throw e;
      }
    };
  • 레파지토리 계층에서:
    // repositories/user.repository.js
    findUserInfo = async (user_id) => {
      try {
        const user = await this.userModel.findByPk(user_id);
        return user;
      } catch (e) {
        e.name = 'Database Error';
        e.message = '요청을 처리하지 못하였습니다.';
        e.status = 500;
        throw e;
      }
    };

각 계층에서 각각 다른 에러 메세지와 코드를 넘겨서, 만약 에러가 발생할 시 어디로부터 기인한 에러인지를 알고자 하였다. 그러나 위와 같이 쓰면 실은 레파지토리 계층에서 에러가 발생했더라도, 서비스 계층의 catch 문을 넘어오면서 e.status와 e.mesage 등이 덮어씌워지는 형국이라 내가 원하는 목적을 이룰 수는 없었다.

알아보니 error.stack이라는 속성으로 에러가 발생한 위치를 파악할 수 있다고 한다.

updateProduct = async (req, res, next) => {
  const { id } = req.params;
  const { product_name, product_price, product_detail, product_image } =
    req.body;
	// ...
  // 상품 업데이트 진행
  try {
    ...
  } catch (error) {
    return res.status(500).json({
      errorMessage: error.message,
      errorStack: error.stack.split("\n")[1].trim(),
    });
  }
};

// => errorStack 값 예시:
"errorStack": "at ProductService.updateProduct (C:\\Users\\...\\services\\product.service.js:52:13)",

⇒ 이와 같이 하면 errorStack에는 에러가 발생한 첫 위치가 담기게 된다.

튜터 문답 - 계층화에서 발생하는 자잘한 고민과 팁

  • 계층을 나누니 예를 들어 유저 정보를 업데이트 한다고 할 때, find메소드로 존재 유무를 검색하는 데에 한 번, 다시 update메소드를 돌릴 때 또 한 번 검색이 발생하게 된다. 이게 처리 속도에 영향을 많이 미칠까 하여 튜터에게 물어보니 findByPk()는 검색 속도가 충분히 빨라서 괜찮고, 만약 findOne 같이 조건절로 훑어야 하는 경우라면 속도에 지장이 꽤 있을 거라고 한다.
  • update 메소드의 서비스 계층에 굳이 find로 존재 유무를 한 번 안 걸러줘도 된다고 하는데… 그러면 레파지토리 계층에서 ‘없음’에 대한 반환값 null에 대하여 에러를 던져주면 되는건가? 레파지토리 계층에서도 그렇게 에러를 처리하기도 하는지 궁금하다.
  • 실무에서 보통은 update나 delete 작업 이후에 수정/삭제된 데이터를 (굳이 확인하려고) res에 담아보내지 않는다고 한다. 처리 후 처리된 행 개수나 단순히 처리됐다/안됐다 정도만 반환한다고 함.
  • 원하는 필드들을 추리거나 데이터를 정렬하는 것 같은 처리는 서비스 계층에서 하는 것보다 레파지토리 계층에서 하는 것을 더 추천한다고 함. 내 생각도 같음.
    • ⇒ 그런 작업은 DB가 처리하는 게 보통 더 빠르기 때문
    • ⇒ 레파지토리에서 처리하게 만들면, 프론트단에서 ‘원하는 필드명들만 인자로 주문받아서’ 해당하는 필드가 테이블에 존재하는지를 보고 존재하면 쿼리하여 가져오는 식으로 만들 수도 있다는 장점이 있다. ‘원하는 필드명’들은 …args로 파라미터를 받으면 프론트단 입장에서는 얼마든지 원하는 필드들을 바꿔 주문할 수 있고, 레파지토리 계층 입장에서는 하나의 메소드만 만들어 그걸로 유연하게 주문을 처리할 수 있게 된다.


Uploaded by N2T

    'TIL | WIL' 카테고리의 다른 글
    • 2/6 월 (잘 되는 것 같기도, 망함을 목전에 두고 있는 것 같기도 한 D-2) TIL
    • 2/4 토 (ejs와 `express-ejs-layouts` 동시 사용시 가능한 url 경로는 오직 query string 방법뿐) TIL, TIT
    • 2/2 목 (다대다 관계 테이블은 이렇게 짜면 된다) TIL, TIT
    • 2/1 수 (4번째 프로젝트 시작) TIL
    깊은바다거북
    깊은바다거북

    티스토리툴바