Fetch API 고쳐쓰기
2024년 4월 22일 by이호연
Vercel 팀은 Next JS에서 Fetch API를 래핑하여 브라우저와 서버에서 캐싱을 지원하는 fetch
함수를 만들었다. 이 함수는 브라우저와 서버에서 동일한 코드로 데이터를 가져올 수 있게 해준다. 하지만 이 함수는 다른 api 클라이언트 라이브러리들 만큼 편리하지는 않다.
기본 사용법
fetch
함수는 기본적으로 다음과 같이 사용할 수 있다.
const response = await fetch('/user/me');
const data = await response.json();
이 코드는 /user/me
에서 데이터를 가져와서 data
변수에 저장한다. 하지만 이 코드는 400 ~ 500 사이의 HTTP 상태 코드를 받으면 에러를 던지지 않는다.
Error를 던지는 fetch 함수 만들기
그래서 나는 이를 해결하기 위해 assert
함수를 만들었다. 이 함수는 Response
객체를 받아서 HTTP 상태 코드에 따라 에러를 던진다.
export default function assertAPI(response: Response) {
if (!response.ok) {
switch (response.status) {
case 400:
throw new Error(BAD_REQUEST);
case 401:
throw new Error(UNAUTHORIZED);
// ...
case 500:
throw new Error(SERVER_ERROR);
default:
throw new Error(UNKNOWN);
}
}
}
이 함수를 사용하면 다음과 같이 fetch
함수를 만들 수 있다.
export async function cfetch(url: string): Promise<any> {
const response = await fetch(url);
assertAPI(response);
return response.json();
}
이제 우리의 fetch
는 400 ~ 500 사이의 HTTP 상태 코드를 받으면 에러를 던진다.
Type-safe한 fetch 함수 만들기
fetch
함수를 사용할 때 가장 불편한 점은 type-safe 하지 않다는 것이다. fetch
함수는 Response
객체를 반환하는데, 이 객체는 어떤 데이터를 가지고 있는지 알 수 없다. 이를 해결하기 위해 fetch
함수를 다음과 같이 고쳤다.
export async function cfetch<Res>(url: string) {
const response = await fetch(url);
assertAPI(response);
return response.json() as Promise<Res>;
}
반복되는 코드 줄이기
fetch
함수를 사용할 때마다 fetch().then(res => res.json())
를 쓰는 것이 불편했다.
또, 메서드를 매번 지정해주는 것도 가독성을 떨어뜨렸다. 그래서 다음과 같이 fetch
함수를 고쳐썼다.