Choorai
| 문서

60분 완주 챌린지

Step 4/6

50%
사전 준비
프론트엔드
백엔드
4
연결
5
배포
6
완료
예상 소요시간: 10분

프론트-백 연결

프론트엔드에서 백엔드 API를 호출하여 실제 데이터를 표시합니다. TanStack Query를 사용해 API 상태 관리를 쉽게 처리해요.

TL;DR (3줄 요약)

  • TanStack Query 설치로 API 호출 관리
  • API 클라이언트 + React hooks 생성
  • 로컬 state를 API 연결로 교체

시작 전 확인

두 서버가 모두 실행 중이어야 합니다:

  • 프론트엔드: http://localhost:5173 (npm run dev)
  • 백엔드: http://localhost:8000 (uvicorn main:app --reload)

1 TanStack Query 설치

프론트엔드 폴더(my-admin)에서 실행하세요:

터미널
# my-admin 폴더에서 실행
npm install @tanstack/react-query

src/main.tsx에 QueryClientProvider를 추가합니다:

src/main.tsx
import React from 'react'
import ReactDOM from 'react-dom/client'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import App from './App'
import './index.css'

const queryClient = new QueryClient()

ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <QueryClientProvider client={queryClient}>
      <App />
    </QueryClientProvider>
  </React.StrictMode>,
)

2 API 클라이언트 생성

src/api/client.ts 파일을 만듭니다:

src/api/client.ts
const API_URL = import.meta.env.VITE_API_URL || 'http://localhost:8000';

class ApiClient {
  private baseUrl: string;

  constructor(baseUrl: string) {
    this.baseUrl = baseUrl;
  }

  async get<T>(path: string): Promise<T> {
    const response = await fetch(`${this.baseUrl}${path}`);
    if (!response.ok) {
      throw new Error(`API Error: ${response.status}`);
    }
    return response.json() as Promise<T>;
  }

  async post<T, D>(path: string, data: D): Promise<T> {
    const response = await fetch(`${this.baseUrl}${path}`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(data),
    });
    if (!response.ok) {
      throw new Error(`API Error: ${response.status}`);
    }
    return response.json() as Promise<T>;
  }

  async delete(path: string): Promise<void> {
    const response = await fetch(`${this.baseUrl}${path}`, {
      method: 'DELETE',
    });
    if (!response.ok) {
      throw new Error(`API Error: ${response.status}`);
    }
  }
}

export const apiClient = new ApiClient(API_URL);

3 React Hooks 생성

src/hooks/useProjects.ts 파일을 만듭니다:

src/hooks/useProjects.ts
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { apiClient } from '../api/client';

// 타입 정의
interface Project {
  id: string;
  name: string;
  description?: string;
  created_at: string;
  updated_at: string;
}

interface ProjectCreate {
  name: string;
  description?: string;
}

interface ProjectListResponse {
  items: Project[];
  total: number;
}

// Hooks
export function useProjects() {
  return useQuery({
    queryKey: ['projects'],
    queryFn: () => apiClient.get<ProjectListResponse>('/api/v1/projects'),
  });
}

export function useCreateProject() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: (data: ProjectCreate) =>
      apiClient.post<Project, ProjectCreate>('/api/v1/projects', data),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['projects'] });
    },
  });
}

export function useDeleteProject() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: (id: string) => apiClient.delete(`/api/v1/projects/${id}`),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['projects'] });
    },
  });
}

4 컴포넌트에서 사용하기

AI에게 기존 컴포넌트를 API 연결 버전으로 수정해달라고 요청합니다:

AI 프롬프트

작업 필요

"기존 App.tsx를 수정해서 API와 연결해줘. 변경사항: 1. 로컬 state 대신 useProjects, useCreateProject, useDeleteProject hooks 사용 2. 로딩 상태 표시 (isLoading) 3. 에러 상태 표시 (isError) 4. 생성/삭제 시 버튼 비활성화 (isPending) 기존 UI는 유지하고, 데이터 소스만 API로 변경해줘. 사용할 hooks: - useProjects() - { data, isLoading, isError } - useCreateProject() - { mutate, isPending } - useDeleteProject() - { mutate, isPending }"

기존 코드를 AI에게 보여주면서 수정 요청하세요.

5 연결 확인

프론트엔드에서 프로젝트를 생성하면 백엔드 API에 저장됩니다.

프론트엔드 :5173
1. 폼에 이름 입력
2. "생성" 버튼 클릭
3. 목록에 추가됨 확인
백엔드 :8000
1. POST 요청 수신
2. 메모리에 저장
3. 201 응답 반환
연결 성공!

프론트엔드에서 생성한 프로젝트가 백엔드 /docs의 GET API에서도 보이면 성공입니다!

CORS 에러가 발생한다면?

브라우저 콘솔에 "CORS" 에러가 보이면 백엔드의 CORS 설정을 확인하세요:

  1. 백엔드 main.py에서 allow_origins 확인
  2. ["http://localhost:5173"]이 포함되어야 함
  3. 백엔드 서버 재시작

자세한 해결 방법은 CORS 트러블슈팅을 참고하세요.

연결 완료 체크리스트

0/4 완료