농산물 가격 정보 프로젝트 마무리

김민기·2022년 10월 3일
0

Project

목록 보기
3/3
post-thumbnail

농산물 실시간/경락 가격 정보

농산물 실시간/경락 가격정보
github

Kapture 2022-10-03 at 14 56 10

원래는 매일매일 기록하면서 프로젝트를 진행하려고 했지만 기록하는게 정말 어렵운 습관이라는 것을 한번 더 깨달았다..

그래서 프로젝트를 진행하면서 기억나는 과정들을 한번에 정리해보려 한다. 내용이 너무 길어지지 않게끔 정리해야지

프로젝트 시작

뜬금없이 갑자기 농산물 프로젝트를 만들줄은 나도 몰랐다. 데브코스를 수료하고 취업준비과정에 들어가면서 스스로를 돌아보게 되었는데, 아무것도 모르는 상태에서 데브코스에 참여한 나로서는 정말 값진 경험과 유익한 시간들이였지만 정리하지 못하고 넘어가는 것들이 너무 많았다

프론트 팀원들과 팀 프로젝트를 진행하기도 했고 백엔드와 협업해서 프로젝트를 진행하기도 했지만 스스로 생각하기에 내가 만든것이 아니라는 느낌이 들었고 취업 준비과정에서 자신감이 너무 부족했다.

이력서를 작성하고 포트폴리오도 작성해야 했지만 내것이 아니라는 느낌 때문에 막막한 느낌만 갖고 있었다.
그러던 중 그냥 쉬러 부모님 집에 내려갔다가 부모님이 자주 사용하시는 농산물 실시간 경매 어플에 문제가 있다는 얘기를 들었다

지금도 문제가 있는지는 모르겠지만 내가 확인했을때는 안드로이드에서 앱을 사용하는 도중에 크래시가 종종 발생했었다. 그 얘기를 듣고 어떤 어플인지 직접 설치해보고 사용해보면서 만들 수 있지 않을까? 라는 생각이 들어서 시작하게 되었다.

API를 찾아라

당연히 농산물 경락 가격이나 정산 가격같은 정보를 내가 찾아낼 수 없고, 또한 서버를 직접 만들어본적이 없기 때문에 사용할 수 있는 API를 찾아보게 되었다. 농산물 경매 라는 주제로 API를 찾았을 때, 정부에서 제공하는 Open API도 있어서 사용하려고 했으나 상당히 부족한 느낌이여서 (명세서를 봐도 이해가 안된다.) 다른 API를 찾던 도중 도매시장 통합홈페이지 페이지를 찾았는데, 여기서 다행히 Open API를 제공하고 있었다. 문제는 트래픽이 100건이라 호출 횟수가 상당히 제한적이라는 점. 추후 운영신청을 해야 트래픽을 늘릴 수 있다고 확인했다.

프로젝트 생성

처음에는 그냥 리액트로 만들어야겠다고 생각했는데, 최근들어 Next.js를 사용하는 회사들도 많아지고 취업에도 도움이 될것 같으며 결정적으로 사이드 프로젝트인데 그냥 하고싶은 프레임워크를 사용해보자라는 마음에 Next.js로 프로젝트를 생성했다. 타입스크립트를 사용하기 위해서 타입스크립트 옵션도 추가했다.

UI 구성

프로젝트 계획 단계에서 생각했던 UI는 위와 같았다. 페이지를 2개 사용해서 실시간 경락 정보 페이지와 정산 가격 페이지를 만들려고 했었다.
하지만 우선적으로 나의 고객으로 볼 수 있는 부모님은 주로 스마트폰을 사용해서 가격 검색을 하셨고, 따라서 페이지도 모바일 우선 전략으로 만들어야 했기 때문에 UI를 수정하고 지금과 같은 모습으로 변경하였다.
UI를 예쁘게 만들기 위해서 나의 디자인 감각보다는 MUI를 사용하도록 했고, 아이콘 또한 MUI에서 가져왔다.

검색 로직

기존에 부모님이 사용하시던 어플을 처음 보았을 때, 농업과 전혀 관련이 없는 나로서는 대분류, 중분류, 소분류를 선택할 수 없었다. 물론 농업을 하는 분이더라도 모를 수도 있다는 생각이 든다.
예를 들어 요즘 부모님께서는 꽈리고추를 농작하셔서 경매장에 판매하셨는데 꽈리고추라는 상품이 어떤 분류에 속하는지 알수 없기 때문에, 어플에서 하나씩 모두 눌러서 찾아보거나 인터넷에 따로 검색하는 방법 밖에 없었다. 나로서는 이런 점이 불편하다 생각했기 때문에 도매시장, 법인명, 상품명 3가지를 사용해서 원하는 상품을 바로 검색할 수 있도록 만들었다.

하지만 심각한 문제가 있었는데, 어플은 무한스크롤로 동작하고 있었고 어떻게 호출하는지 모르겠지만 일정 갯수만큼 화면에 보여주고 그 이상이 될 경우(또 호출을 하는지는 모르겠다.)다음 목록을 보여주고 있었는데

우선 API에서 보내주는 데이터 1페이지의 데이터 수가 1000건이였다. 요청 데이터 수를 내가 변경할 수는 없었고 무조건 1페이지에 1000건이 들어오고 다음으로 2페이지를 요청하면 다시 1000건이 넘어오는 방식이었다. 따라서 데이터가 1000건이면 무한스크롤을 할 수가 없다고 판단했고, 어쩔수 없이 데이터를 모두 가져오는 방식을 선택했다.

경매장에 정말 많은 경매 건수가 발생하지만 (6000 ~ 8000건 정도 되는 듯하다.) 한 가지의 작물에 대해서 1000개 이상의 경매 건수가 발생하지는 않을거라 생각한다.

검색 로직 세분화

도매시장 정산 가격정보의 경우 요청 변수가 다음과 같았고

실시간 경락 가격 정보의 경우 요청변수가 아래와 같다.

실시간 경락 가격정보는 말그대로 실시간이기 때문에 날짜가 없다. 요청변수의 갯수가 다르기 때문에 코드의 중복을 줄여보려 했으나 타입스크립트에서 옵셔널 프로퍼티로 만들었을 때 undefined 관련 에러가 계속 나왔고 결국에는 any로 쓰고 있어서 그냥 로직을 따로 분리했다.

에러 처리

API를 호출했을 때 다음과 같은 에러가 발생할 수 있다.

처음에는 혼동했던게 Axios에서 이 에러를 잡아줄수 있다고 생각해서 Axios 에러처리를 계속해서 찾아보고 있었는데, Axios는 위와 같은 에러가 오더라도 상태가 200으로 정상이 되기 때문에 Axios에서 에러처리를 하는 것이 아니였다.
확인해본 결과 Axios 호출에 성공해서 데이터를 가져오는 경우와 Axios 호출에 실패했을 때 error 데이터를 가져오는 경우가 있어서 response에 data 객체가 있을 경우 정상적으로 상품 목록 컴포넌트를 보여주고 실패할 경우 error 객체의 내용을 보여주도록 만들었다.

API Key 숨기기

여기서는 serviceKey로 사용하는 API Key가 .env 파일을 사용했음에도 요청시에 보여지고 있었다. 지금은 그냥 개발용 API이기 때문에 누구든 사용해도 문제 없지만(복잡한 절차 없이 신청만 해도 우선 100건의 데이터 호출은 가능하다!) 배포하고 추후에 운영까지 하게 된다면 API key는 반드시 숨겨야함으로 Next.js에서 API를 숨기는 방법을 찾아보았다.

처음에는 서버리스 함수를 사용하려고 했으나, API Url은 이미 rewrite를 사용해서 마스킹하고 있기 때문에 큰 의미가 없어 보였다. 그리고 나서 검색을 해보니 dotenv 패키지를 설치하면 env 파일에 있는 내용들을 감출 수 있다고 했었는데 전혀 작동하지 않았고 dotenv를 사용하는 방법을 따라하다보니 node.js가 아니기 때문에 fs 관련 에러가 발생했다. 찾아보니 CRA로 만든 프로젝트에서는 기본적으로 사용할 수 있다고 한다.(REACT_PUBLIC 같은 접두사를 반드시 사용한다. 여기서는 NEXT_PUBLIC~ 사용했음)

이것저것 찾아보던 중 마땅한 방법이 없어보였는데 답은 생각보다 가까운데 있었다. 이미 rewrite를 사용했기 때문에 destination에 API Key를 같이 작성해서 해결하였다.

/** @type {import('next').NextConfig} */
const nextConfig = {
  reactStrictMode: true,
  swcMinify: true,
  async rewrites() {
    return [
      {
        source: "/agromarket-settle",
        destination: `${process.env.NEXT_PUBLIC_API_SETTLEMENT_PRICE}?serviceKey=${process.env.NEXT_PUBLIC_API_KEY}`,
      },
      {
        source: "/agromarket-realtime",
        destination: `${process.env.NEXT_PUBLIC_API_REALTIME_PRICE}?serviceKey=${process.env.NEXT_PUBLIC_API_KEY}`,
      },
    ];
  },
};

module.exports = nextConfig;

마무리

아직 리팩토링 할게 엄청 많아보이지만 사실 몇일 전부터 리팩토링 과정을 거치고 있었다. 리팩토링을 완전히 끝내고 배포하고 싶었지만 너무 길어질것 같은 마음에 우선적으로 기능이 잘 작동하도록 만들고 배포했다.

프로젝트를 진행하면서 정말 별일들이 많이 있었지만 기록해두지 않은 점이 아쉽다. 그냥 생각나는 것은 상품 목록 컴포넌트에서 map을 사용할 때, 콘솔을 찍기 위해 한줄 추가하다보니 { }괄호를 사용하게 되었고 return은 추가하지 않아서 정상적으로 호출됬음에도 아무런 데이터도 넘어오지 않는 에러를 경험했고 API 호출에 문제가 있는게 아닌가 싶어서 다른 방향으로 엄청 삽질한 경험이 있다...

또한 타입스크립트를 사용하면서 타입들을 정리할 때 적절한 이름을 짓는게 정말 어렵다는 것을 다시 한번 느낄수 있었고 React를 사용해서 내가 원하는 프로젝트를 만들었다는 성취감이 좋았다

사실 다 만들고나니 페이지가 전혀 필요없는 웹페이지가 되어서 Next.js를 사용한 의미가 무엇일까 생각도 들었는데, CORS 방지와 API Key를 쉽게 감출 수 있다는 점에서 유의미하다고 생각한다.

추가적으로 다 만들고나서 부모님께 보여드렸는데 내 생각과는 전혀 다른 답변이 나왔다. 내 생각에는 저렇게 분류를 파고들어가는게 불편하다는 것이였는데, 부모님 생각은 검색하는 것보다 터치 몇번 해서 내가 원하는거 보는게 더 편하고 말씀하셨다. 역시 혼자만의 생각에 갇혀서 뭔가를 만들다 보면 놓치는 것들이 많다는 것을 느꼈다
부모님과 더 자세히 얘기해본 결과 아는 작물에 대해서는 터치 몇번이 더 편할 수 있지만 모르는 경우에는 검색을 하는것이 더 편하다. 또한 검색한 작물이 어떤 분류에 속하는지 보여지면 더 좋을 것 같다라는 의견을 반영해서
현재 생각으로는 최근 검색어 저장 기능을 만들어서 간단하게 바로 검색할 수 있도록 만들어보려 한다.

간단할줄 알았는데 API를 검색하는 것도, 혼자서 Axios를 사용하는 것, 디자인, 컴포넌트 설계 등 모든 것을 고려하다보니 중요한 git을 놓친것 같다. 한번 배포하고 나서는 issue를 적극적으로 사용하고 있지만 이전에는 그냥 main 브랜치에서 작업하고 모두 커밋해버렸다...

끝나고 나니 부족한점만 보이는게 사실인것 같다. 엄청 대단하고 완성도 높은 프로젝트는 아닐지여도 재밌는 주제로 재밌게 만들어본 경험이라 생각한다.

0개의 댓글