콘텐츠로 이동

Handling API Requests

공통적으로 사용하는 API 요청 로직은 shared/api 폴더에 보관하는 것을 권장합니다. 이렇게 하면 애플리케이션 전체에서 일관된 방식으로 재사용할 수 있고, 초기 구현 속도(프로토타이핑)도 빠르게 유지할 수 있습니다.

대부분의 프로젝트는 다음 구조와 client.ts 설정만으로 충분합니다.

일반적인 파일 구조 예시:

  • 디렉터리shared/
    • 디렉터리api/
      • client.ts
      • index.ts
      • 디렉터리endpoints/
        • login.ts

client.ts 파일은 모든 HTTP request 관련 설정을 한 곳에서 관리합니다. 즉, 공통 설정을 client에 모아두면 개별 endpoint 로직에서는 request를 보내는 데만 집중할 수 있습니다.

client.ts에서는 다음 항목들을 설정합니다:

  • 백엔드 기본 URL
  • Default headers (예: 인증 header)
  • JSON 직렬화/파싱

아래 예시에서 axios 버전과 fetch 버전 모두 확인할 수 있습니다.

shared/api/client.ts
// Axios 예시
import axios from 'axios';
export const client = axios.create({
baseURL: 'https://your-api-domain.com/api/',
timeout: 5000,
headers: { 'X-Custom-Header': 'my-custom-value' }
});

이제 shared/api/endpoints 폴더 안에 API endpoint별 request 함수를 작성합니다. 이렇게 endpoint 단위로 분리해두면 API 변경이 있을 때 유지보수가 매우 쉬워집니다.

shared/api/endpoints/login.ts
import { client } from '../client';
export interface LoginCredentials {
email: string;
password: string;
}
export function login(credentials: LoginCredentials) {
return client.post('/login', credentials);
}

그리고 다음처럼 shared/api/index.ts에서 request 함수와 타입들을 공개 API로 내보냅니다:

shared/api/index.ts
export { client } from './client'; // If you want to export the client itself
export { login } from './endpoints/login';
export type { LoginCredentials } from './endpoints/login';

특정 페이지나 feature 내부에서만 사용하는 request는 해당 slice의 api 폴더에 넣어 관리하는 것을 권장합니다. 이렇게 하면 slice별 코드가 서로 섞이지 않고, 책임이 명확하게 분리되며, 유지보수가 쉬워집니다.

예시 구조:

  • 디렉터리pages/
    • 디렉터리login/
      • index.ts
      • 디렉터리api/
        • login.ts
      • 디렉터리ui/
        • LoginPage.tsx
pages/login/api/login.ts
import { client } from 'shared/api';
interface LoginCredentials {
email: string;
password: string;
}
export function login(credentials: LoginCredentials) {
return client.post('/login', credentials);
}

이 함수는 로그인 페이지 내부에서만 사용하는 API 요청 이므로 slice의 public API(index.ts)로 다시 export할 필요는 없습니다.

API 타입과 클라이언트 자동 생성

섹션 제목: “API 타입과 클라이언트 자동 생성”

백엔드에 OpenAPI 스펙이 준비되어 있다면, orval이나 openapi-typescript 같은 도구를 사용해 API 타입과 request 함수를 자동으로 생성할 수 있습니다.

이렇게 생성된 코드는 보통 shared/api/openapi 같은 폴더에 두고, README.md에 다음 내용을 함께 문서화하는 것을 권장합니다.

  • 생성 스크립트를 어떻게 실행하는지
  • 어떤 타입/클라이언트가 생성되는지
  • 사용하는 방법 예시

TanStack Query (React Query)Pinia Colada 같은 서버 상태 관리 라이브러리를 사용할 때는, 서로 다른 slice에서 타입이나 cache key를 공유해야 할 때가 자주 생깁니다.

이런 경우에는 다음과 같은 항목들을 shared layer에 두고 같이 쓰는 것이 좋습니다.

  • API 데이터 타입 (API data types)
  • 캐시 키 (cache keys)
  • 공통 query/mutation 옵션 (common query/mutation options)