6.1장: FastAPI와 프론트엔드 연결하기
학습 시간: 30분
1. '하이퍼 드라이브'로의 복귀: 프로토콜 비교
지난 장에서는 우리 관제 센터(프론트엔드)를 'ISS'(Laravel API)와 도킹했습니다. 이제 우리는 초광속 전투기(FastAPI)로 돌아가 동일한 작업을 수행할 것입니다.
이 장의 목표는 단순히 작업을 반복하는 것이 아니라 두 가지 접근 방식을 비교하는 것입니다. 마치 동일한 드래곤 우주선이 먼저 ISS와 도킹한 다음, 중국의 '톈궁' 우주정거장과 도킹하는 것과 같습니다. 도킹 노드는 동일하지만(REST), 절차와 포트 위치에 미묘한 차이가 있을 수 있습니다.
💡 우주 비유:
과정은 동일합니다: 접근하고, 정렬하고, 도킹합니다. 하지만 'ISS'의 경우
/api/planets
포트를 사용해야 했고, '톈궁'의 경우/spaceships
포트를 사용해야 했습니다. 우리 관제 센터의 운영자는 임무를 성공적으로 수행하기 위해 이러한 세부 사항을 알아야 합니다.
2. 전투기(FastAPI) 도킹 준비
이 작업은 4.2장에서 이미 했지만, 모든 것이 제자리에 있는지 확인해봅시다.
1단계: FastAPI 서버 시작
- Laravel 서버가 실행 중인 경우 중지합니다 (포트 충돌 방지).
- FastAPI 프로젝트 폴더에서 터미널을 엽니다.
-
가상 환경을 활성화합니다:
- Windows:
.\venv\Scripts\Activate.ps1
- macOS / Linux:
source venv/bin/activate
- Windows:
-
서버를 시작합니다:
서버는http://127.0.0.1:8000
주소에서 접근할 수 있습니다.
2단계: main.py
에서 CORS 설정 확인
FastAPI 프로젝트에 이전에 추가한 CORSMiddleware
가 설정되어 있는지 확인하십시오. 프론트엔드 주소로부터의 요청을 허용해야 합니다.
# main.py
from fastapi.middleware.cors import CORSMiddleware
# ...
origins = [
"http://127.0.0.1:5500", # Live Server 주소
"null", # file:///을 위함
]
app.add_middleware(
CORSMiddleware,
allow_origins=origins,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# ...
3. 관제 센터의 '안테나'를 FastAPI로 재설정
이제 가장 흥미로운 부분입니다. JavaScript에 FastAPI와 다시 작동하도록 해야 할 최소한의 변경 사항입니다.
1단계: 기본 URL 변경
api.js
를 열고 API_BASE_URL
을 원래 값으로 되돌립니다.
// api.js
// 우리 FastAPI API의 URL을 지정합니다
const API_BASE_URL = 'http://127.0.0.1:8000'; // <-- /api 없음!
// ... 나머지 apiRequest 코드 ...
2단계: FastAPI 응답 구조에 맞게 조정
FastAPI의 GET /spaceships
가 페이지네이션이 있는 객체가 아닌 단순 배열을 반환한다는 것을 기억합시다. 이는 fetchAndDisplayFleet
코드를 원래 형태로 되돌려야 함을 의미합니다.
app.js
의 fetchAndDisplayFleet
함수를 수정하세요:
// app.js
async function fetchAndDisplayFleet() {
try {
fleetListContainer.innerHTML = '<p>FastAPI에서 원격 측정 데이터를 로드 중...</p>';
const ships = await apiRequest('/spaceships'); // <-- /spaceships로 요청
// FastAPI에서는 단순 배열이므로 .data 키가 필요 없습니다!
fleetListContainer.innerHTML = '';
if (ships.length === 0) {
fleetListContainer.innerHTML = '<p>등록된 기기가 없습니다.</p>';
return;
}
ships.forEach(ship => {
// 카드 생성을 위한 원래 함수로 되돌립니다
const card = createShipCard(ship);
fleetListContainer.appendChild(card);
});
} catch (error) {
fleetListContainer.innerHTML = `<p style="color: #ff6b6b;">함대 로드 오류: ${error.message}</p>`;
}
}
// 함선 카드 생성을 위한 원래 함수
function createShipCard(ship) {
const card = document.createElement('div');
card.className = 'card';
card.innerHTML = `
<h3>${ship.name} (ID: ${ship.id})</h3>
<p>유형: ${ship.type}</p>
<p>발사 연도: ${ship.launch_year}</p>
<p>상태: ${ship.status}</p>
<div class="card-actions">
<button class="edit-btn" data-ship-id="${ship.id}">수정</button>
<button class="delete-btn" data-ship-id="${ship.id}">폐기</button>
</div>
`;
return card;
}
3단계: CRUD 작업 확인
FastAPI의 Pydantic 모델과 HTML 폼 필드(name
, type
, launch_year
, status
)가 일치하므로, handleSaveShip
및 handleDeleteShip
함수는 /spaceships
엔드포인트를 대상으로 이미 작동하도록 설정되어 있으므로 변경 없이 작동해야 합니다.
4. 비교 결과: 프론트엔드 개발자에게 이것은 무엇을 의미하는가?
- REST의 보편성: 백엔드가 REST 원칙을 따른다면 프론트엔드에게는 백엔드가 무엇으로 작성되었는지(PHP/Laravel 또는 Python/FastAPI) 중요하지 않다는 것을 분명히 확인했습니다.
- 문서의 중요성: 주요 차이점은 엔드포인트 URL과 JSON 응답 구조에 있었습니다. 이것이 바로 API 문서에 설명되어야 할 내용입니다. 문서가 없다면 프론트엔드 개발자는 '맹목적으로' 작업하게 될 것입니다.
- 프론트엔드의 유연성: JavaScript 코드는 다양한 데이터 형식(예:
data
키가 있는지 또는 단순 배열인지 확인하는 등)에 쉽게 적응할 수 있을 만큼 충분히 유연해야 합니다.
결론: REST API 작업 능력은 모든 현대적인 백엔드와의 상호 작용 문을 여는 보편적인 열쇠입니다.
정리 퀴즈
🚀 챕터 요약:
당신은 성공적으로 CUC의 "통신 프로토콜"을 전환했고, 두 가지 다른 백엔드 시스템과의 작업을 실질적으로 비교했습니다.
- ✅ 서버 간 전환을 위한
API_BASE_URL
설정 기술을 익혔습니다. - ✅ 응답 구조(
data
대 단순 배열)의 중요성과 이에 프론트엔드를 어떻게 적용해야 하는지 이해했습니다. - ✅ 좋은 프론트엔드 개발자는 어떤 RESTful API와도 작업할 준비가 되어 있어야 하며, 해당 문서를 주의 깊게 연구해야 한다는 것을 깨달았습니다.
범용 연결 기술을 습득했습니다! 이제 기본적인 연결을 설정하는 방법을 알았으니, CORS, 인증, 보안과 같은 더 복잡한 프로토콜에 대해 이야기할 차례입니다.
📌 확인:
- FastAPI 서버가 실행 중인지 확인하십시오.
app.js
의API_BASE_URL
과 응답 처리 로직을 FastAPI용으로 되돌렸는지 확인하십시오.- 프론트엔드가 FastAPI 백엔드와 모든 CRUD 작업을 다시 올바르게 수행하는지 확인하십시오.
⚠️ 오류 발생 시:
- CORS 오류: FastAPI 서버가 올바른 CORS 설정으로 실행 중인지 확인하십시오.
Cannot read properties of undefined (reading 'length')
오류:responseData
에서.data
에 대한 접근을 제거하는 것을 잊었을 수 있습니다.- 404 Not Found:
API_BASE_URL
을 확인하십시오 — FastAPI에는/api
접두사가 없습니다.