Bleeding edge

Axios로 간이 api mocking 세팅하기 본문

Javascript

Axios로 간이 api mocking 세팅하기

codevil 2023. 8. 14. 09:46

프론트와 백엔드가 원하는 것들이 완벽한 타이밍에 구현이 세팅된다면 이를 고민할 필요가 없겠지만, 개발은 항상 원하는 대로 진행되지 않는다. 지난번 프로젝트에서는 서버 dto가 변경되는 경우를 고려하지 않고 구현을 하여서, 서버 dto가 변경되는 경우에 많은 비용을 사용하였던 경험이 있었다. 이번에는 이 경험을 살려서 dto를 좀 더 flexible하게 코드를 짰기 때문에 dto 변경은 부드럽게 대응하였다. 하지만 특정 페이지의 정보를 서버에서 받아올 때 서버에서 구현이 안된 경우에 개발이 살짝 지연되었던 것이 아쉬웠었다. 아무래도 그 기간이 서버팀이 많이 바쁜기간이라 그랬던 것도 있었지만, 내가 api mocking을 쉽게 하였다면 좋았을 것 같다고 생각해서 axios로 간이 api mocking을 만드는 방법에 대해 고민하였다.

Step 1. Input에 필요한 값과 Output에 필요한 값 고민하기

1. Input - endpoint: axios나 fetch를 보낼 때 어느 엔드포인트에 request를 하는지를 알아야한다.

2. Output - enabled : 이 값이 유효한지 안한지를 알아야한다.(없는 엔드포인트가 있는 경우를 고려)

3. Output - response : 원하는 엔드포인트로 값을 호출한 경우 보낼 response

 

Step 2. Output 파일 생성 및 예시로 만들기

//api.mockup.ts
export const mockup = {
  "": {
    enabled: process.env.NODE_ENV === "development",
    response: "[]"
  },

  "/board/1": {
    enabled: process.env.NODE_ENV === "development",
    response: {
      id: 1,
      title: "Red velvet",
      desc: "빨간맛"
    }
  }
};

 

Step 3. Axios를 이용하여 원하는 값을 받기

//axios의 기본 설정은 https://codevil.tistory.com/291 를 참조하자!
//만일 간이로 만들고 싶다면 baseURL을 비워도 괜찮다.
import { apiUrlStorage } from "./api.strorage";
import { apiPathStorage } from "./api.path";
class ApiService {
  private readonly axiosInstance = axios.create({
    baseURL: apiUrlStorage.baseUrl, 
    timeout: 60000
  });
  public async getEndpoint(){
  	const { data } = await this.axiosInstance.get(apiPathStorage.endpointExample);
  }
  //api.mock.ts에 값이 존재하고 enabled이면 mock.ts에서 response를 return 없는 경우는 undefined
  private getMockData(mockup, endpoint) {
    const mockupValue = mockup?.[endpoint];
    const hasMockupKey = !!mockupValue;
    const isEnabled = !!mockupValue?.enabled;
    const inValidReturn = undefined;
    return hasMockupKey && isEnabled ? mockupValue?.response : inValidReturn;
  }
  
  //adapter를 이용하여 들어가는 값을 조절한다.
  private readonly axiosRequestOption = this.axiosInstance.interceptors.request.use(
    (request) => {
      const mock = this.getMockData(mockup, request?.url || "");
      if (!mock) return request;
      return {
        ...request,
        adapter: (config) => {
          return new Promise((resolve) => {
            const request = {
              data: mock,
              status: 200,
              statusText: "OK",
              headers: { "content-type": "text/plain; charset=utf-8" },
              config,
              request: {}
            };
            return resolve(request);
          });
        }
      };
    },
    (err) => new Promise(err)
  );
}

export const apiService = new ApiService();

adapter라는 것이 있다는 것을 알기 이전에는 intercepter response부터 intercepter request그리고 transformedRequest 다양한 방법을 시도하였지만, 둘 다 원하는 결과 값은 나왔지만 404 에러가 나왔기 때문에 원하는 대로 만들어졌다고 생각을 하지 않아서 다른 방법을 고민하다가 adapter를 적용하니.. 너무나 쉽게 끝나서 살짝 허무했다.

 

마무리

이번에 설정한 api mocking을 사용하여 앞으로 간단한 기본 값 같은 경우에는 이 방법을 통하여 해결할 수 있을 것 같다. 모두 구현하는 것도 좋지만 이렇게 많이 쓰는 라이브러리 같은 경우에는 라이브러리에 대한 세팅을 검색해서 사용하기 좋게 만드는 것도 나쁘지 않은 것 같다.