728x90
반응형
SMALL
이번 강의에서는 FastAPI로 간단한 Todo 리스트 백엔드를 구축하고, 해당 API의 OpenAPI 스펙을 통해 swagger-typescript-api로 클라이언트 코드를 자동 생성하는 전 과정을 살펴봅니다. 이를 통해 실제 프로젝트와 유사한 상황을 체험해볼 수 있을 것입니다.
1. FastAPI로 간단한 Todo 백엔드 구성하기
1) FastAPI 설치
먼저 Python 환경에서 FastAPI와 Uvicorn을 설치해줍니다.
pip install fastapi uvicorn sqlalchemy
2) 프로젝트 구조 예시
fastapi-todo/
├── main.py
└── requirements.txt
- main.py에 라우팅, 모델, API 로직을 정의합니다.
3) Todo 모델 및 API 라우팅
main.py:
# backend/main.py
from typing import Annotated, Optional, List
from fastapi import FastAPI, HTTPException, Depends, Query
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel
from sqlmodel import Field, Session, SQLModel, create_engine, select
app = FastAPI(
title="Todo API",
description="A simple Todo list application using FastAPI",
version="1.0.0"
)
# CORS 구성
origins = [
"http://localhost:5173",
]
app.add_middleware(
CORSMiddleware,
allow_origins=origins,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# 시작시 데이터베이스 생성
@app.on_event("startup")
def on_startup():
create_db_and_tables()
# 데이터베이스 엔진 생성
sqlite_file_name = "database.db"
sqlite_url = f"sqlite:///{sqlite_file_name}"
connect_args = {"check_same_thread": False}
engine = create_engine(sqlite_url, connect_args=connect_args)
# 데이터베이스 생성함수
def create_db_and_tables():
SQLModel.metadata.create_all(engine)
# 데이터베이스 세션 제공
def get_session():
with Session(engine) as session:
yield session
SessionDep = Annotated[Session, Depends(get_session)]
# SQL Model
class TodoItem(SQLModel, table=True):
id: int | None = Field(default=None, primary_key=True)
title: str = Field(index=True)
description: Optional[str] = Field(default=None)
done: bool = False
# API 엔드포인트 (CRUD)
@app.get("/todos", response_model=List[TodoItem])
def get_todos(
session: SessionDep,
offset: int=0,
limit: Annotated[int, Query(le=100)] = 100
) -> list[TodoItem]:
todos = session.exec(select(TodoItem).offset(offset).limit(limit)).all()
return todos
@app.post("/todos", response_model=TodoItem)
def create_todo(session: SessionDep, todo: TodoItem, ) -> TodoItem:
session.add(todo)
session.commit()
session.refresh(todo)
return todo
@app.get("/todos/{todo_id}", response_model=TodoItem)
def get_todo_by_id(session: SessionDep, todo_id: int):
item = session.get(TodoItem, id)
if not item:
raise HTTPException(status_code=404, detail="Item not found")
return item
@app.put("/todos/{todo_id}", response_model=TodoItem)
def update_todo(session: SessionDep, todo_id: int, todo_in: TodoItem):
todo = session.get(TodoItem, todo_id)
if not todo:
raise HTTPException(status_code=404, detail="Item not found")
update_todo = todo_in.model_dump(exclude_unset=True)
todo.sqlmodel_update(update_todo)
session.add(todo)
session.commit()
session.refresh(todo)
return todo
@app.delete("/todos/{todo_id}")
def delete_todo(session: SessionDep, todo_id: int):
todo = session.get(TodoItem, todo_id)
if not todo:
raise HTTPException(status_code=404, detail="Item not found")
session.delete(todo)
session.commit()
return {"message": "Item deleted successfully"}
- TodoItem: Pydantic 모델을 사용해 Todo 데이터 구조를 명세합니다.
- 엔드포인트:
- GET /todos: 전체 Todo 목록 조회
- POST /todos: Todo 생성
- GET /todos/{todo_id}: 단일 Todo 조회
- PUT /todos/{todo_id}: Todo 수정
- DELETE /todos/{todo_id}: Todo 삭제
4) 서버 실행
uvicorn main:app --reload
- 기본 포트: http://127.0.0.1:8000
- API 문서: http://127.0.0.1:8000/docs
- OpenAPI 스펙: http://127.0.0.1:8000/openapi.json

2. OpenAPI 스펙 확인하기
FastAPI는 자동으로 /openapi.json 엔드포인트를 제공합니다. 이 엔드포인트가 **swagger-typescript-api**에서 참조할 OpenAPI 스펙이 됩니다.
- 예: http://127.0.0.1:8000/openapi.json
- 구조: FastAPI가 작성한 엔드포인트 정보를 바탕으로 OpenAPI 3.0.2 형식의 JSON을 자동 생성합니다.
- 활용: 이를 그대로 swagger-typescript-api 도구에 넘겨, 클라이언트를 자동 생성할 수 있습니다.

3. swagger-typescript-api를 이용한 클라이언트 코드 생성
1) 개발 환경
- Node.js, npm(or Yarn) 설치되어 있다고 가정합니다.
- 원하는 폴더에서 npm init -y 등을 통해 패키지 초기화 후, swagger-typescript-api를 설치합니다.
npm install swagger-typescript-api --save-dev
2) 명령어 실행
FastAPI 서버가 동작 중인 상태에서, OpenAPI JSON URL을 --path 옵션에 전달해줍니다.
npx swagger-typescript-api \
--path "http://127.0.0.1:8000/openapi.json" \
--output "./src/generated" \
--name "ApiClient.ts"
- --path: 스펙 파일(또는 URL) 경로 지정. 여기서는 FastAPI가 제공하는 URL을 사용합니다.
- --output: 생성된 파일 저장 폴더 (예: ./generated)
- --name: 결과 파일명 (예: TodoApiClient.ts)
4. 생성된 클라이언트 코드 살펴보기
명령어 실행이 완료되면 ./generated/TodoApiClient.ts 파일이 생성됩니다. 내부를 확인해보면, 대략 다음과 같은 요소들이 자동으로 포함됩니다.
/* eslint-disable */
/* tslint:disable */
/*
* ---------------------------------------------------------------
* ## THIS FILE WAS GENERATED VIA SWAGGER-TYPESCRIPT-API ##
* ## ##
* ## AUTHOR: acacode ##
* ## SOURCE: https://github.com/acacode/swagger-typescript-api ##
* ---------------------------------------------------------------
*/
/** HTTPValidationError */
export interface HTTPValidationError {
/** Detail */
detail?: ValidationError[];
}
/** TodoItem */
export interface TodoItem {
/** Id */
id: number;
/** Title */
title: string;
/** Description */
description?: string | null;
/**
* Done
* @default false
*/
done?: boolean;
}
// 이하 생략
- 인터페이스(Interface) 정의: TodoItem과 같은 Pydantic 모델을 그대로 TypeScript 타입으로 변환.
- 메서드: 각 경로(GET /todos, POST /todos, 등)에 해당하는 함수들이 자동 생성.
Tip: axios 옵션을 사용하면 Axios 기반 코드로 생성되며, Fetch API 기반으로도 생성 가능합니다. 프로젝트 스타일에 맞춰 사용하세요.
6. 마무리 & 정리
- FastAPI를 통해 OpenAPI 스펙을 손쉽게 얻을 수 있습니다.
- **swagger-typescript-api**는 이 스펙을 활용하여 자동화된 TypeScript 클라이언트 코드를 생성해주며, 타입 안정성과 생산성을 크게 높여줍니다.
- Todo 리스트와 같은 간단한 예제에서도 충분히 체감할 수 있는 장점이 있으니, 실제 업무에 적용하면 더 큰 효과를 얻을 수 있습니다.
다음 4강에서는 React(Vite) 프로젝트와 연동하여 화면에 데이터를 표시하는 과정과, 협업 효율을 높일 수 있는 베스트 프랙티스들을 살펴보겠습니다.
728x90
반응형
LIST