언젠가는 펼쳐 볼 아카이브

[엘리스 SW 트랙] 1차 프로젝트 : 오피스아워 코멘트 9주차 - 2 본문

IT/엘리스 SW 트랙 7기

[엘리스 SW 트랙] 1차 프로젝트 : 오피스아워 코멘트 9주차 - 2

개발자희망생고롸파덕 2023. 11. 23. 02:17

 

코드 리뷰

// orderService.js 일부
...
    orderBody.id.length < 1 ||
    orderBody.items.length < 1 ||
    orderBody.address.length < 1 ||
    orderBody.addressDetail.length < 1 ||
...
  • 값에 대한 검증을 length 로 검증하는 것 보다는 명시적으로 id === null 혹은 !id 같은 구문을 표시 해주는 게 더 읽기 쉽습니다.
//orderService.js 일부

...
const getOrder = async (id, order) => {
  const user = await User.findOne({ email: id }).exec();
  let data;

...
  • 변수는 사용하기 바로 전에 선언하는게 보기 편합니다. 함수 전체를 관통하는 let result; 와 같은 변수라면 차라리 함수 최상단에 선언해 주세요.
// orderService.js 일부

const getOrder = async (id, order) => {
...
}
  • 이 함수의 기능은 보기에는 "주문을 가져오기" 지만 더 나눠보면 "주문을 사용자의 Id 로 가져오기" 와 "주문을 사용자의 Id와 주문번호로 가져오기 (단일주문)" 두 가지의 기능이 합쳐져 있는 함수입니다. 두 내용 자체가 API path 가 다르게 구성되어야 합니다.
  • host/api/users/:user_id/orders (users/:user_id 는 생략가능), host/api/orders/:order_id 따라서 orderService 에서도 getOrdersByUserId, getOrderById 이렇게 두 개로 동작을 구분 해 주는게 더 이해하기 편하실 겁니다.
// adminService.js 일부

const getUserOrder = async (id, user_id, order_id) => {
  let data;

  if (!isAdmin(id)) {
    throw new APIError(httpStatus.UNAUTHORIZED, 'User is not Admin');
  }

  if (!(await User.findOne({ email: user_id }))) {
    throw new APIError(httpStatus.NOT_FOUND, 'User is not Exist');
  }
...
  • 하나의 워크플로우에서 (ex. 사용자 주문정보 가져오기) 중복된 db 쿼리를 수행하는 것은 추후에 서비스가 커졌을 때 고스란히 비용으로 바뀝니다. 보통 값의 올바름에 대한 Validation 을 진행할 때 위와 같은 현상이 많이 발생하는데요. 논리적으로 코드를 읽기 가능하다는 가정하에는 db 쿼리 호출을 최소화 하는게 좋습니다.
  • 예를 들어, adminService.js 에 있는 isAdmin(userId) 이라는 함수는 내부에서 User 모델에 접근하여 userId 에 해당하는 사용자를 가져온 뒤 권한을 체크하는데요. 이 isAdmin 이 사용되는 Controller 에서 User.find() 가 같이 호출되는 부분이 그 예시 입니다. 이 경우에는 jwt payload 에 있는 role 로 사용자의 권한을 구분하거나 혹은 아예 isAdmin 을 middleware chain 으로 만들어 req.user = User.findOne({email: id}); 으로 다음 chain 에서 사용자의 정보를 활용할 수 있게 하는게 더 좋아보입니다.

 

현업&코드 작성 관련 코멘트

  • "좋은 코드"를 작성하고 싶은데, 혹시 작성할 때 팁이 있을까요?
    • 진부한 답일지도 모르겠지만, 좋은 코드를 작성하려면 "어떤 코드가 좋은 코드인지 볼 수 있는 안목"이 필요합니다. 그래야 그 코드가 좋은 코드라는 것을 알고, 배울 수 있겠죠. 그렇다면 어떻게 좋은 코드를 볼 수 있는 눈을 가질 수 있을까요? 다양한 경험을 해보는 방법도 있고, 책을 보는 방법도 있습니다. 
    • 책을 통해 배우는 방법도 좋은 방법 중 하나입니다. 읽어보면 좋은 책 추천해드릴게요. 책에 있는 모든 내용이 정답이라는 것은 아니지만, 좋은 코드라는 것을 볼 수 있는 안목을 키워주기엔 좋을 겁니다 :)
  • 현재 다양한 라이브러리들이 존재하고, 개발자들은 라이브러리들을 많이 사용하는데요. 라이브러리들을 쓸 때 주의해야한다거나, 어떻게 사용하면 좋다..라는 것이 있을까요?
    • 라이브러리 사용할 때의 주의해야 할 점은.. document에 명시되어있는대로 사용해야한다는 것이겠네요.
    • 라이브러리를 잘 사용하려면 내가 사용한 라이브러리가 어디서, 어떻게 동작하는지 알아야합니다. 아, 내가 이 라이브러리를 왜 사용하는지도 잘 알고 있어야 겠네요.
  • 어떤 걸 공부하는 게 좋을까요? express 말고 추천해주실 수 있을까요?
    • 음.. 백엔드 쪽은 후에 Nest.js 를 사용해 보시는걸 추천드려요. 아, 그리고 객체지향 공부도 꾸준히 하셔야합니다 ㅎㅎ
    • 만약 언어가 java라면, 우리나라에서는 spring이 대체적으로 많이 쓰이고 있으니 spring 공부 하는 것도 추천드립니다.
  • 실제 현업에서 개발할때는 프론트/백엔드 개발중에 좀 더 먼저 선행되어야하는 개발이 있을까요?
    둘다 동시에 진행될 것 같긴 한데, 이번 프로젝트를 하면서 느낀게 백엔드쪽 API가 없으면 프론트 단에서 개발하는데 조금 차질이 있을 것 같은 생각이 듭니다. 현업에서도 프론트 쪽은 임시 데이터를 가지고 개발을 하는지, 아니면 백엔드가 살짝 먼저? 작업을 진행한 후에 프론트엔드 작업을 진행하는지 여쭤보고 싶습니다.
    • 프론트에서는 백엔드 api 가 나오기 전 까지는 먼저 가상의 데이터로 작업을 진행해줍니다. 현업에서는 설계기간이 있기 때문에 그 사이에 api 들 구조는 대략 구성이 완료됩니다. 백엔드에서 보통 예상 가능한 범위 내에서 가상 데이터를 알려주고, 프론트에게 이거 맞춰서 먼저 작업해달라고 말씀을 드리죠. 뭐가 선행되어야 하는건 따로 없는 것 같아요
  • 만약에 프론트 쪽에서 가상 데이터를 가지고 개발하다가 추가로 필요한 데이터가 있을 수도 있을것 같은데..
    API 개발 중간에 백엔드 쪽에 추가 요청을 하는 경우도 자주 있을까요?
    • 네 맞아요. 자주 있는 일입니다. 아무래도 실제 기획이 변경되어 화면 구성이 조금 바뀌게 되면 API 를 추가하거나 변경해주는 경우도 있습니다. 여기서 이제 보통 트러블이 시작이 되는데요. 백엔드 기준으로는 api 두개 호출하거나 프론트에서 알아서 데이터를 맞춰 주면 될 것 같은데, 프론트에서 새로운 api를 만들어달라거나 값을 정제해서 달라거나 하는경우에요.
    • 근데 반대로 프론트 입장에서는 컴포넌트를 다 구조화 해놓고, 함수도 다 만들어 놨는데.. 데이터에 대한 처리를 다시해야 할 때, 보통 요청합니다. 
    • 회사마다 다르긴 하지만, 저 같은 경우는 이런거는 그때그때 조율해서 프로젝트가 마무리 될 수 있는 최선의 방향으로 작업을 합니다.
      • 그래도 백엔드 입장에서 원칙은 "API 를 화면에 맞춰주지 않는다" 이긴합니다. 왜냐면 이 API 서버라는게 웹 어플리케이션도 쓰고, 앱도 쓰고, 외부에서 쓸 수도 있기 때문에 그렇습니다.
      • 화면에 맞춰주지 않는다..가 좀 애매할 수도 있겠네요ㅠㅠ; 데이터에 한정해서 화면이랑 완벽하게 1:1로 맞춰주지 않는다는거지, PATCH, PUT 설명드릴때 말씀드렸었는데요. API 구성은 기획 기준으로 작성합니다.

 

#엘리스트랙 #엘리스트랙후기 #리액트네이티브강좌 #온라인코딩부트캠프 #온라인코딩학원 #프론트엔드학원 #개발자국비지원 #개발자부트캠프 #국비지원부트캠프 #프론트엔드국비지원 #React #Styledcomponent #React Router Dom #Redux #Typescript #Javascript