0ju-log
💻 Frontend

[RTK Query] transformResponse

⚙️ transformResponse

transformResponse ? 서버의 엔드포인트를 통해 받은 response를 클라이언트에서 가공할 수 있도록 하는 옵션이에요

  • 해당 API를 호출하여 사용하는 데이터는 transformResponse를 자동적으로 거치게 되고, 가공된 데이터를 사용할 수 있어요

ex) 차트 데이터가 월별로 정렬되지 않은 데이터

transformResponse: (res: ITransactionSummary) => {
    const sorted = res.series.sort((a, b) => a.month.localeCompare(b.month));
    return { ...res, series: sorted };
  },
BEFORE : 월별로 정렬되지 않은 차트
BEFORE : 월별로 정렬되지 않은 차트
AFTER : 월별로 정렬된 차트
AFTER : 월별로 정렬된 차트

🖥️ 트러블 슈팅

서버에서 받는 response의 타입과 transformResponse의 타입이 달라서 오류가 발생했어요

  • 서버에서 받는 response의 items : ITask[]
  • transformResponse를 통해 가공한 response의 items : Record<string, ITask[]>

⇒ transformResponse에 중심을 맞춰 타입을 일치시켜야 해요!

getMissingTaskList: builder.query<
MissingTasksByMonth
, number>({
    query: (powerPlantId) => ({
      url: `/powerplants/${powerPlantId}/tasks/missing`,
    }),
    transformResponse: (res: IMissingTaskList): 
MissingTasksByMonth
 => {
      return buildMissingTasks(res);
    },
  }),

❓ 근데 진짜 궁금한 게 있슨

getMissingTaskList를 통해 받는 response의 타입 : IMissingTaskList transformResponse로 인해, query의 response 타입 자리에 IMissingTaskList가 아닌 MissingTasksByMonth가 대신 들어가게 되는데요

이렇게 해도 쿼리문이 타입 에러 없이 성립할 수 있는 이유가 뭔지에 대해 궁금했어요

⇒ builder.query의 response type은 transformResponse가 어떤 타입의 응답을 반환할 것인지를 정의하는 것이기 때문에 transformResponse의 res 타입의 경우, 서버로부터 받은 데이터인 baseQuery의 타입 구조와만 일치하면 되는 거였어요

📝 정리

원래는 걍 쌩데이터만 받고 데이터 가공을 하는 유틸함수를 따로 만들거나, 변수를 재지정해서 선언하는 방식으로 진행했었는데 transformResponse를 통해 재가공한 데이터를 API 호출하면 바로 사용할 수 있다는 사실이 너무 신기했던 것 같아요!

서버에서 보통 데이터를 정렬하긴 하나, 내 쪽에서 한 번 더 가공을 해줘야 서버 데이터가 바껴도 그나마 안전하게 데이터를 사용하고 보여줄 수 있다는 사실을 깨닫게 되었어요. 어쩌면 DX를 꽤 향상시키는 옵션이라고 생각해요.

비록 RTK Query를 많이 쓰지 않아 자주 쓰는 라이브러리인 tanstack-query에서도 같은 기능을 하는 옵션이 있나 찾아봤더니 select 라는 옵션이 있다고 해요! 이번에 공부한 내용을 꼭 기억하여 기능을 추후 애용할 거에요 😊

🔗 참고