제주 여행지 추천 서비스 ⌜여기올레⌟ 프론트엔드 서버 구현

이은지·2022년 1월 3일
0
post-custom-banner

나의 제대로된 첫 프로젝트! 백지에서부터 홈페이지와 컴포넌트 구성을 해본 것도, axios로 백엔드 통신을 해본 것도 모두 처음이었다. 왕 재밌고 왕 뿌듯했어서 velog에도 기록! 🥳 앞으로 더 많은 기능을 섭렵해나가고 싶당. 자세한 프로젝트 정보는 해당 링크에서 확인하실 수 있습니당 👉 여기올레 프로젝트 깃허브 링크

컴포넌트 단위 개발의 용이성을 고려했을 때, 순수 Javascript보다는 프레임워크를 사용하는 것이 적합하다고 판단했습니다. 또한 프로젝트의 크기가 작지 않고, Redux를 활용해보고 싶었기 때문에 React를 택하게 되었습니다.

1. 컴포넌트 구성

  • 첫 접속 화면(Home)
  • 여행유형테스트 질문 화면
  • 여행유형테스트 결과 화면
  • 장소 입력 화면(출발지, 도착지, Must Visit Place)
  • 최종 결과 화면

Redux를 사용한 중앙집중식 상태관리를 구현하고자 했기 때문에, 컴포넌트들은 단순히 Redux store에 저장되어 있는 정보를 화면에 뿌려주고, dispatch를 통해 reducer에 요청을 보내는 역할만을 담당하게끔 작성했습니다.

다만 여행유형테스트 의 데이터(질문 및 선지, 여행유형별 설명)의 경우 고정된 데이터일 뿐 아니라 해당 컴포넌트에서만 사용되는 데이터였기 때문에 Redux store가 아닌 js 파일에 별도로 저장 후 import/export하여 사용합니다.

2. React-redux를 활용한 상태 관리

Reducer 구성

여기올레 프로젝트에서 프론트엔드 서버가 관리해야 하는 데이터는 크게 두 종류입니다.

  • 여행유형테스트 관련 데이터
    • 사용자의 여행 유형 테스트 응답
    • 백엔드 서버로부터 받아온 여행 유형 결과
  • 장소 관련 데이터
    • 사용자가 입력한 장소(출발지, 도착지, Must Visit Place)
    • 백엔드 서버로부터 받아온 최종 여행지 추천 결과

따라서 각 데이터 별로 reducer를 만들고, combineReducers를 활용해 rootReducer로 통합했습니다.

각 reducer에서 수행한 작업

각 reducer에서는 아래의 작업들을 수행합니다.

  • 컴포넌트에서 입력 받은 사용자의 응답을 저장
  • 사용자의 응답을 백엔드 서버로 전송
  • 백엔드 서버로부터 응답 받아오기

실제 코드기반 설명

실제 코드 및 실행 화면과 함께 reducer와 컴포넌트, 백엔드 서버가 어떻게 상호작용했는지 살펴보겠습니다. (비동기처리 및 Axios 통신에 관한 상세한 설명은 우선 생략하고, 추후 기술하겠습니다.)

스크린샷 2022-01-02 오후 9 12 44 reducers/typeResult.js의 초기상태

input : 질문별 사용자의 응답값을 저장할 배열

result : 백엔드 서버로부터 받아올 여행유형 결과를 담을 변수

status : POST요청 성공 여부를 담을 변수


스크린샷 2022-01-02 오후 9 25 13 스크린샷 2022-01-02 오후 9 42 00

질문별 화면에서 사용자가 “다음으로” 버튼을 누르게 되면, 해당 버튼의 onClick 이벤트가 발생합니다. onClick 이벤트에서는 사용자의 응답을 담은 dispatch 액션 객체가 전송됩니다.

마지막 질문까지 동일한 방식으로 진행되며 input 배열에 응답이 차례로 저장됩니다.


스크린샷 2022-01-02 오후 9 25 47

마지막 질문이 끝나면 테스트 결과 페이지로 이동합니다.

스크린샷 2022-01-02 오후 9 45 54

useEffect 를 사용해 TestResult 컴포넌트가 첫 렌더링 되는 시점에 서버에 POST 요청을 보내는 액션객체를 전송하도록 했습니다. TestResult 컴포넌트가 렌더링 되면서 액션객체를 전송하면, reducer는 사용자의 응답을 담은 input 배열을 json 형식으로 변환해 서버에 전송합니다.

(위 코드의 getTypeResult 함수는 redux-thunk middleware의 thunk함수입니다.)


스크린샷 2022-01-01 오후 2 30 57

POST 요청이 성공하여 여행유형결과를 받아오는데 성공하면, 결과값(정수 id)을 reducer내 result 에 저장합니다. TestResult 컴포넌트는 해당 결과값에 해당하는 유형 정보를 사용자에게 제공합니다.

3. 백엔드 통신 Axios

여기올레 API 명세서

API명세서를 기반으로 백엔드 서버와 HTTP 통신을 진행했습니다. 이때 HTTP 비동기 통신 라이브러리인 Axios를 활용했습니다.

POST 요청을 통한 데이터 전송

HTTP 요청은 비동기 작업이기 때문에 요청 횟수를 최소화하는 편이 오류발생을 줄일 수 있겠다고 생각했습니다. 따라서 사용자가 새로운 응답을 입력할 때마다 서버로 데이터를 보내는 것이 아니라 배열, 객체에 응답을 차례로 저장해두었다가 결과 페이지 로딩 시 저장해둔 응답 데이터를 전송합니다.

여행유형테스트 결과 페이지, 최종 결과 페이지 로딩 시 POST 요청을 통해 서버에 전송한 데이터의 예시입니다.

스크린샷 2022-01-03 오후 12 49 09

사용자가 선택한 선지에 상응하는 스코어값을 담은 배열을 서버로 전송합니다.

스크린샷 2022-01-03 오후 12 50 55

사용자가 지도 상에서 선택한 출발지, 도착지의 위도와 경도, Must Visit Place의 key값을 한 객체에 담아 전송합니다. 로그인 기능을 구현하지 않았기 때문에 새로고침 시 사용자에 대한 데이터가 리셋됩니다. 따라서 사용자의 여행유형응답(score)과 여행유형결과(type)를 reducers/place.js 의 store에도 저장해두고, 장소 정보 전송 시 다시 한 번 서버에 전송합니다.

Redux-thunk, async&await를 활용한 비동기처리

스크린샷 2022-01-03 오후 2 22 07

Redux에서의 API 호출을 위해 Redux-thunk 미들웨어를 사용합니다.

스크린샷 2022-01-03 오후 1 55 57

액션객체는 순수한 객체(plain object)여야 하기 때문에, HTTP 통신을 통해 받은 response를 액션객체에 바로 담아서 전송하면 에러가 발생합니다. 따라서 plain object 형태의 액션객체를 반환하는 thunk함수를 정의합니다. thunk함수는 try-catch구문을 사용하여 HTTP 요청이 성공하면 성공 결과를, 실패하면 에러 코드를 담은 액션 객체를 반환합니다.

스크린샷 2022-01-03 오후 1 57 03

reducer에 정의된 thunk함수를 결과 제공 컴포넌트에서 import해 사용합니다. thunk함수의 인자로 사용자 응답 데이터를 보내면, thunk함수에서 이를 POST요청 body에 담아 서버로 전송합니다. 요청이 성공하면 응답으로 받아온 결과를 담은 액션객체를 리턴합니다. 결과 제공 컴포넌트는 리턴된 액션객체를 reducer에 dispatch합니다.

스크린샷 2022-01-03 오후 1 57 24

reducer는 액션객체에 담긴 결과값을 반영해 state를 업데이트 합니다. 결과 제공 컴포넌트는 업데이트된 state를 참조해 사용자에게 결과를 제공합니다.

스크린샷 2022-01-03 오후 2 37 16

baseURL 설정

스크린샷 2022-01-03 오후 2 39 18

localhost:3000 이 아닌 실제 서버로 HTTP요청을 보내기 위해 axios 인스턴스 생성 시 baseURL을 설정합니다. 백엔드 서버와 통신해야 하기 때문에 포트번호를 8080으로 지정했습니다.

post-custom-banner

0개의 댓글