본문 바로가기

JS Ecosystem

(버그 수정) Axios를 활용한 HTTP 요청 처리와 DELETE 요청 문제 해결

 

Axios는 JavaScript에서 HTTP 요청을 간단하고 직관적으로 처리할 수 있는 라이브러리로, fetch API를 사용할 때 발생할 수 있는 JSON 파싱 이슈를 신경 쓰지 않고도 손쉽게 사용할 수 있는 장점이 있습니다.

 

프로젝트를 진행하면서 GET, POST 등 HTTP 요청이 반복적으로 사용되다 보니 이를 공통 모듈화하여 효율성을 높이고, 유지보수성을 강화하고자 했습니다. 그 결과로 createAxiosConfig라는 커스텀 함수를 작성하여 사용하게 되었습니다.

1. 커스텀 함수로 요청 구성하기

복잡한 HTTP 요청 설정이 반복적으로 사용될 경우, 이를 하나의 함수로 분리하면 코드의 재사용성을 높이고 가독성을 향상시킬 수 있습니다. createAxiosConfig는 요청 메서드, URL, 데이터, 헤더 등을 구성하는 역할을 하며, Axios 요청 생성을 더 간편하게 만들어줍니다.

초기 버전: createAxiosConfig

const createAxiosConfig = (
  method,
  url,
  data = null,
  customHeaders = {}
) => {
  const headers = {
    "Content-Type": data 
    ? (!(data instanceof FormData) 
       ? "application/json" 
       : "multipart/form-data") : undefined,
    ...customHeaders,
  };

  return {
    url,
    method,
    data,
    withCredentials: true,
    headers,
  };
};

 

이 함수는 HTTP 요청 생성 시, 반복적으로 작성해야 하는 axios 메서드와 headers, body를 손쉽게 구성할 수 있도록 도와줍니다. 특히, 다양한 요청 메서드(GET, POST, PUT, PATCH, DELETE)와 함께 사용할 수 있도록 설계되었습니다.

 

2. DELETE 요청에서 발생한 문제

이 함수는 대부분의 요청에서 잘 동작했지만, DELETE 요청에서 문제가 발생했습니다. DELETE 요청은 일반적으로 본문 데이터를 포함하지 않는 경우가 많지만, createAxiosConfig는 data를 기본값으로 null로 설정하고 있었기 때문에 DELETE 요청에도 data: null이 포함되도록 구성되었습니다.

 

결과적으로, 서버로 전송된 요청에는 불필요한 Content-Type 헤더가 포함되었고, 이로 인해 다음과 같은 오류가 발생했습니다:

Executing (61d3d5ca-5ea9-4ee2-91d7-e0ee44039199): START TRANSACTION;
Executing (61d3d5ca-5ea9-4ee2-91d7-e0ee44039199): ROLLBACK;
PATCH /branch/451/branch-images 400 2.531 ms - 54
SyntaxError: Unexpected token n in JSON at position 0
    at JSON.parse (<anonymous>)
    at createStrictSyntaxError (/Users/holystory/sideprj/is_home/server/node_modules/express/node_modules/body-parser/lib/types/json.js:160:10)
    at parse (/Users/holystory/sideprj/is_home/server/node_modules/express/node_modules/body-parser/lib/types/json.js:83:15)
    at /Users/holystory/sideprj/is_home/server/node_modules/express/node_modules/body-parser/lib/read.js:128:18
    at AsyncResource.runInAsyncScope (node:async_hooks:203:9)
    at invokeCallback (/Users/holystory/sideprj/is_home/server/node_modules/express/node_modules/raw-body/index.js:231:16)
    at done (/Users/holystory/sideprj/is_home/server/node_modules/express/node_modules/raw-body/index.js:220:7)
    at IncomingMessage.onEnd (/Users/holystory/sideprj/is_home/server/node_modules/express/node_modules/raw-body/index.js:280:7)
    at IncomingMessage.emit (node:events:517:28)
    at endReadableNT (node:internal/streams/readable:1368:12)
    at process.processTicksAndRejections (node:internal/process/task_queues:82:21)

 

이 에러는 DELETE 요청에서 data: null이 JSON 파싱 중 예상치 못한 데이터로 처리되어 발생한 문제입니다.

 

3. 문제 해결

이 문제를 해결하기 위해 여러 방안을 검토했습니다. 우선 createAxiosConfig를 사용하지 않고 아래와 같이 간단히 DELETE 요청을 처리하는 방법을 고려했습니다.

const handleDelete = async () => {
  try {
    const response = await axios.delete(`${baseUrl}/branch/${selectedBranchData.id}`);
    if (response.status === 200) {
      console.log("Branch deleted successfully.");
    }
  } catch (error) {
    console.error("Error deleting branch:", error);
  }
};

 

이 방식은 DELETE 요청에 불필요한 data를 포함하지 않고 간단히 동작하지만, 프로젝트에서 공통적으로 사용하는 요청 설정(예: headers, withCredentials)을 중복 작성해야 하는 단점이 있었습니다.

 

개선된 createAxiosConfig 함수

따라서, 공통 모듈화를 유지하면서 DELETE 요청에서도 불필요한 데이터와 헤더를 제거할 수 있도록 createAxiosConfig를 다음과 같이 개선했습니다.

const createAxiosConfig = (method, url, data = null, customHeaders = {}) => {
  const headers = {
    ...(data 
      ? { "Content-Type": !(data instanceof FormData) 
        ? "application/json" : "multipart/form-data" }
        : {}),
    ...customHeaders,
  };

  const config = {
    url,
    method,
    withCredentials: true,
    headers,
  };

  if (data) {
    config.data = data; // DELETE 요청에서도 데이터가 필요한 경우만 추가
  }

  return config;
};

 

이 개선된 함수는 data가 없는 경우 Content-Type 헤더를 설정하지 않도록 처리하여 DELETE 요청에서도 불필요한 헤더나 데이터가 포함되지 않도록 했습니다.

 

4. 결론

DELETE 요청의 특성과 이를 해결하기 위한 createAxiosConfig 함수의 개선 과정을 통해 다음과 같은 결론을 얻었습니다:

  1. 단순한 DELETE 요청: 간단한 DELETE 요청은 axios.delete를 바로 호출하여 처리할 수 있습니다.
  2. 공통 모듈화의 필요성: 반복적으로 사용되는 설정은 공통 모듈화를 통해 관리하는 것이 유지보수와 확장성 측면에서 유리합니다.
  3. 요청 메서드별 특성 고려: DELETE 요청처럼 데이터가 없는 경우가 많은 요청은 불필요한 데이터와 헤더가 포함되지 않도록 처리해야 합니다.

개선된 createAxiosConfig 함수는 다양한 요청 메서드에 유연하게 대응하며, DELETE 요청에서도 안정적으로 동작하도록 설계되었습니다. 이를 통해 코드의 일관성과 효율성을 유지할 수 있었습니다.