React

API Service

HTTP 통신을 위한 API Service 사용에 대한 내용입니다.

해당 기능은 공통업무 기능입니다. 다음과 같이 미리 준비된 Boilerplate confy-app 형태로 제공됩니다.
API Service 기능은 axios, react-query 라이브러리를 사용하여 구현되어 있습니다.

주요 구성 요소

  • 구조화된 API 통신 패턴을 제공합니다. API 통신은 다음 주요 구성 요소로 이루어져 있습니다.
  • API 클라이언트 - Axios 기반 HTTP 클라이언트
  • 에러 처리 - 통합된 API 에러 처리 메커니즘

API 폴더 구조

─ src
├── api/
│ ├── endpoints/ # API 엔드포인트 정의
│ │ ├── index.ts # 엔드포인트 내보내기
│ │ ├── global.endpoint.ts # 전역 관련 엔드포인트
│ │ └── post.endpoint.ts # 게시물 관련 엔드포인트
│ ├──services/ # API 서비스 (요청 처리 함수)
│ │ ├── global.service.ts # 전역 관련 서비스
│ │ └── post.service.ts # 게시물 관련 서비스
├── shared
│ ├── stores/ # store 함수
│ │ ├── siteinfo.store.ts # 기초데이터 store
│ │ └── userinfo.store.ts # 사용자정보 store
└── types/
├── index.d.ts # 타입 내보내기
├── global/ # 전역 관련 타입
│ ├── auth.d.ts # 인증 관련 타입
│ ├── message.d.ts # 메시지 관련 타입
│ ├── siteinfo.d.ts # 사이트 정보 관련 타입
│ ├── user.d.ts # 사용자 관련 타입
│ └── version.d.ts # 버전 관련 타입
└── post/ # 게시물 관련 타입
└── post.d.ts # 게시물 타입 정의
  • api/endpoints/ API 엔드포인트 정의 - 모든 API 경로 관리
  • api/services API 서비스 - 엔드포인트를 사용한 실제 데이터 요청 함수
  • types/ API repsonse 구조 정의

응답데이터 형식

interface ApiResult<T> {
data: T // 실제 데이터
result: {
statusCode: number // 상태 코드
message: string // 메시지
timestamp: string // 타임스탬프
}
}

Usage

요청 흐름

  • apiClient.ts → 인스턴스 생성 및 설정
  • ***.endpoint.ts → API 경로 정의
  • ***.service.ts → 엔드포인트 사용 함수 정의
  • api-error.ts → 에러 처리

1.Endpoint 작성

예시) 게시글 API Endpoint 작성: post.endpoint.ts

const APP_API_URL = import.meta.env.VITE_APP_API_URL
export const POST_ENDPOINTS = {
POST: {
GET_ALL: `${APP_API_URL}/post/get-all`,
GET_BY_ID: (id: string) => `${APP_API_URL}/post/get-by-id/${id}`
}
}

2.응답데이터 형식 추가

예시) 게시글 Interface 작성: post.d.ts

import { ApiResult } from '@/types/apiResult'
export interface Post {
id: number
title: string
content: string
tag: string
createdAt: string
updatedAt: string
// deletedAt: string
}
export interface PostsResponse extends ApiResult<Post[]> {}
export interface PostResponse extends ApiResult<Post> {}

3.Service 작성

예시) 게시글 Service 작성: post.service.ts

import { clientInstance } from '@/shared/utils/apiClient'
import { Post, PostResponse, PostsResponse } from '@/types/post/post'
import { POST_ENDPOINTS } from '../endpoints/post.endpoint'
export const postService = {
getAll: async (): Promise<Post[]> => {
const response = await clientInstance.get<PostsResponse>(
POST_ENDPOINTS.POST.GET_ALL
)
return response.data.data
},
getById: async (id: string): Promise<Post> => {
const response = await clientInstance.get<PostResponse>(
POST_ENDPOINTS.POST.GET_BY_ID(id)
)
return response.data.data
}
}

4.컴포넌트 내 사용

예시) 게시글 불러오기 작성 /src/pages/menu1/pages/page1.tsx

import { postService } from '@/api/services/post.service'
import { useQuery } from '@tanstack/react-query'
const PostList = () => {
const {
data: posts,
isLoading,
error,
refetch
} = useQuery({ // <- react-query 사용
queryKey: ['posts'],
queryFn: () => postService.getAll(),
enabled: false
})
...
return (
<div className='posts-container'>
<h1>게시물 목록</h1>
<div className='posts-grid'>
{posts.map((post) => (
<div key={post.id} className='post-card'>
<h2>{post.title}</h2>
<p>{post.content}</p>
<div className='post-meta'>
<span className='tag'>{post.tag}</span>
<span className='date'>
{new Date(post.createdAt).toLocaleDateString()}
</span>
</div>
</div>
))}
</div>
</div>
)
}
export default function Page1() {
return <PostList />
}

react-query 라이브러리는 따로 추상화를 하지 않았으며, 필요한 옵션을 그때 그때 사용하여 구현해 주세요.

참고