Skip to content

API 요청 처리에 대하여 #43

@seongbin9786

Description

@seongbin9786

API 요청 처리에 대하여

간단하게 써봤습니다. API 요청을 처리하는 것은 어렵진 않은데 생각치 못한 곳에서 막히거나 손이 많이 갈 수 있기 때문에 case 별로 여기 적힌 것보다 추가적인 시나리오가 있을 수 있습니다 😄

추가해야 할 필요가 있는 내용이나 부족한/틀린 부분이 있다면 Comment 남겨주세요!

그 외 토론거리도 Comment 남겨주세요 :) 감사합니다.

Axios 기본

  1. baseURL을 지정하여 새 인스턴스를 만들어서 사용

    const api = axios.create({
        baseURL: ServerConfig.ROOT_URL,
    });
  2. 토큰 때문에 Authorization 헤더를 지정하여 사용

  3. (1), (2)를 적용: /utils/api.js 사용

Action Creator와 Axios

  1. redux-thunkredux-promise와 같이 비동기 작업을 해결할 수 있게 해주는 middleware 사용
  2. redux-thunk 예시 (우리 프로젝트는 thunk만 있기 때문...)
    api.post('/api/endpoint', bodyData)
        .then(({ data }) => { // then은 2xx의 응답인 경우, catch는 그 외의 응답인 경우
            const { prop1, prop2 } = data;
            dispatch({
                type: API_CALL_RESPONSE_SUCCESS,
                payload: { prop1, prop2 },
            });
        });

API 호출 과정에서의 오류 처리

  1. Axios 공식 문서 - Handling Errors 참고
  2. Axios Cheat Sheet 참고 (이 문서는 오류 처리에만 관한 게 아님. API 요약본)

API와 로딩 UI/UX 문제

  1. 비동기 요청이므로 세 가지 상태를 갖게 됨

    • 방안 1: 매번 ACTION TYPE, REDUCER의 Case를 만든다
      1. 요청의 시작과 동시에: PENDING
      2. 응답이 성공인 경우: SUCCESS
      3. 응답이 실패인 경우: REJECTED
    • 방안 2: Action의 payloadPromise로 넘기는 대신 저런 Action의 정의를 자동화
      • redux-promise-middleware가 자동화 함
      • redux-thunk에는 적용 불가인게 dispatch로 직접 요청 성공 이후에 딱 1회 호출하기 때문
  2. (1)을 기준으로 로딩 등의 화면 요구사항이 있을 수 있음

    • 방안 1: Reducer에서 각 요청의 액션 상태를 redux store에 저장한 후 그걸 mapStateToProps로 받아와 각 액션마다 관리하는 방법
    • 방안 2: react-redux-loading-bar를 이용해 redux-promise-middleware의 pending, success, rejected 상태 발생 시 자동으로 로딩 바를 띄우는 방법 (코드 필요 없음 - 로딩 바만 디자인 하면 됨)

결론

  1. redux-promise-middleware를 사용하고, payload에 axios.post(...)와 같이 Promise를 바로 싣거나 new Promise(...)로 감싸고, redux-promise-loading-bar를 이용해 로딩 화면을 자동화 하면 코드 중복이 없다.
  2. 수동으로 해도 되지만 매번 boilerplate가 있는 것은 어쩔 수가 없다. 그러나 이 방법은 더 쉽고 자유도가 더 있으며 이 애플리케이션이 아직 확장성을 따지지 않아도 될 만큼 작기 때문에 상관 없을지도 모른다. (예: 다른 로딩 UI가 필요한 경우 - 어떨 땐 spinner, 어떨 땐 progressive bar)
  3. 아니면 (1)과 (2)를 모두 지원하는 로딩 라이브러리를 새로 작성해도 좋을 듯 (이 쪽이 더 맘에 듦)

redux-promise-middleware + redux-promise-loading-bar 예제

이 Wiki참고

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions