여러 UI 코드가 API 서버가 정의한 응답 스키마에 철저히 의존하고 있을 때 응답 스키마가 변경된다면? 우리는 모든 remote data
호출 코드를 조사해 수정해주어야 합니다. 이러한 강한 의존성으로 인해 유지보수가 힘들어 질 때 즈음 새로운 아이디어를 얻게 되었습니다. 본문은 이 새로운 아이디어를 코드로 풀어내는 내용을 담고있습니다. 재미있게 봐주세요.
Remote Data
를 요청할 때 우리는 다음과 같이 fetcher
함수를 만들어 요청하게 됩니다.
// caching 함수는 이해하지 않으셔도 됩니다. 리모트 데이터를 캐시하는 동작을 하는 코드구나 라고 생각해주세요
export const getProductList = () => {
const cacheKey = `${API_URL}/products`;
return caching((): Promise<any> => {
return productAPI.get('');
}, cacheKey);
};
GET /products endpoint
에서 반환하는 응답 스키마는 다음과 같습니다.
이 경우 상품 데이터를 보여주는 모든 UI 코드에서는 다음과 같은 코드들이 작성될 것입니다.
const {
data: { products },
} = await getProductList();
renderProducts(products);
이러한 상황에서 응답 스키마가 다음과 같이 변경된다면 ?
{
productList: [
{
id: 1,
name: '과자',
price: 1000,
stock: 20,
imageURL: 'http....',
},
{
id: 2,
name: '소주',
price: 2000,
stock: 15,
imageURL: 'http....',
},
],
};
또는
{
product: {
list: [
{
id: 1,
name: '과자',
price: 1000,
stock: 20,
imageURL: 'http....',
},
{
id: 2,
name: '소주',
price: 2000,
stock: 15,
imageURL: 'http....',
},
],
},
};
우리는 상품 데이터를 출력하는 모든 UI 코드들을 조사
해 다음과 같이 코드 수정을 진행해야합니다.
const {
data: { productList:products },
} = await getProductList();
renderProducts(products);
// or
const {
data: { product:{list:products} },
} = await getProductList();
renderProducts(products);
상품 리모트 데이터를 출력하는 코드가 몇군데 없다면 문제가 되지 않지만 매우 많다면?
일일히 노가다 해주어야하기에 휴먼에러를 발생할 수도 있고, 개발 비용(시간적인)을 낭비할 수도 있습니다.
모든 리모트 데이터 사용처에서 백엔드의 응답 데이터를 참조하게 하기 보단 하나의 중간 다리를 두어 응답 데이터를 프론트엔드 입맛대로 가공하여 조회하게 하는 것은 어떨까? 그렇게 한다면 API 서버의 response schema 가 변경되더라도 중간 다리만 수정하면 되니깐 유지보수에 용이하지 않을까?
이를 위해 가공하는 어떠한 함수 혹은 클래스를 만들어 호출하는 코드를 짜볼까 하였으나 axios API
에는 이미 이러한 동작을 하게끔 하는 옵션이 있다.
axios
문서에 따라 response
를 프론트엔드 단에서 수정하는 코드를 작성해보자면 다음과 같다.
// fetcher
export const getProductList = () => {
const cacheKey = `${API_URL}/products`;
return caching((): Promise<any> => {
return productAPI.get('', {
transformResponse: transformer[getProductList.name],
});
}, cacheKey);
};
// response transformer
export const transformer = {
getProductList: stringResponse => {
const parsedData = JSON.parse(stringResponse);
if (parsedData.error) {
return parsedData;
}
return parsedData.products,
},
};
위 같이 코드를 작성하게 되면 모든 productList
데이터 사용처의 코드는 다음 코드로 통일되게 된다.
const {
data: products,
} = await getProductList();
renderProducts(products);
remote data
를 요청하는 프론트엔드 단의 코드는 백엔드의 응답 스키마가 변경되어도 바꿀 필요없는 굳건한 코드가 된다. (실제 백엔드의 응답 데이터를 조회하는 것이 아닌 프론트엔드 단에서 수정한 응답 데이터를 조회하게 되므로)
응답 스키마가 변경되어도 transformer
함수만 수정하면 되므로 유지보수에 훨씬 용이한 코드가 된다!! (👻👻👻)
무수한 관중들의 박수..(zzz 그냥 슬랙에 올라와서 이모지 반응한 것일지도 모르지만..)
난 이런거에 설렘을 느끼는 사람인가보다.. 뭔가 마약같다고 생각하게된다.. 이러한 관심 속 설렘이 자꾸 새로운 생각을 하게끔 해준다.. 나는 관종인가부다..👻!
What if the API server's response structure changes and several UIs depend on it? waffle game
If something doesn’t work right away, don’t give up! It may take time, but if you keep trying, eventually it will work out just fine! nerdle
와 진짜 좋은 글입니다! 일일히 ctrl + shift + f 눌러서 바꿔줬었는데 꿀팁 감사해요!