SW/Python

FastAPI로 CRUD API 만드는 방법: Issue Tracker 예제로 배우는 실전 FastAPI 입문

얇은생각 2026. 2. 7. 07:30
반응형

진짜로 써먹는 Issue Tracker API 만들기 — 기초부터 배포까지

솔직히 말하면, 예전에 저도 이런 경험이 있었어요. “API 강의”라고 해서 들었는데, 40분 동안 구조 이야기만 하다가 코드 한 줄도 안 치고 끝나는 영상들. 머릿속엔 개념만 둥둥 떠다니고, 손에는 아무것도 안 남는 느낌이죠.

그래서 이번에는 방향을 완전히 반대로 잡았습니다.

이번 글에서는 FastAPI crash course를 통해 실제로 돌아가는 Issue Tracker API를 처음부터 끝까지 만들어봅니다. CRUD는 기본이고, Pydantic schema, Swagger docs, middleware, CORS 설정, 그리고 Render 배포까지 전부 다룹니다.

AI 도구를 아예 안 쓰진 않아요. 타이핑을 조금 줄여주니까요. 하지만 핵심은 여전히 같습니다. 왜 이렇게 구성하는지, 각 요소가 무슨 역할을 하는지를 이해하는 것.

 

“AI는 코드를 만들어줄 수 있지만, 시스템을 이해하는 건 결국 사람 몫이다.”

 

우리가 만들 API는 이런 걸 할 수 있어요.

  • Issue 생성
  • Issue 목록 조회
  • 특정 Issue 조회
  • Issue 수정
  • Issue 삭제

 

데이터 저장은 일부러 JSON 파일을 씁니다. 단순해서 좋아요. FastAPI 자체에 집중하기 딱 좋거든요. Node.js + Express 경험이 있다면, 중간중간 비교도 같이 해볼게요.

 

FastAPI, 정확히 뭐길래 이렇게 인기일까?

 


FastAPI, 정확히 뭐길래 이렇게 인기일까?

FastAPI는 Python 기반의 고성능 API framework입니다. 이름 그대로 “빠른 API”를 만드는 데 최적화되어 있죠.

내부적으로는 Starlette라는 ASGI toolkit 위에 올라가 있습니다. Starlette가 담당하는 건 이런 것들이에요.

  • routing
  • middleware
  • request / response 처리

 

FastAPI는 그 위에서 개발자 경험을 확 끌어올립니다.

  • Python type hint 기반 Pydantic validation
  • 자동 serialization
  • Swagger UI / ReDoc 자동 생성
  • Dependency Injection 시스템
  • OAuth2, JWT 같은 security utilities
  • WebSocket, streaming 지원

 

Express로 API 만들다가 “이걸 왜 내가 다 직접 설정해야 하지?” 싶었던 적 있다면, FastAPI는 꽤 시원한 해답처럼 느껴질 거예요.

 

 

ASGI vs WSGI, 왜 중요한데?

이건 살짝만 짚고 갈게요.

  • WSGI: 전통적인 방식, 기본적으로 synchronous
  • ASGI: 비동기 처리 가능, 동시에 여러 request 처리

 

이번 프로젝트에서는 JSON file을 쓰기 때문에 async의 이점을 100% 쓰진 않아요. 하지만 SQLAlchemy 2.0 async 같은 걸 붙이면 FastAPI의 진짜 장점이 드러납니다.

트래픽이 늘어도 API가 버벅이지 않는 그 느낌, 아마 나중에 체감하게 될 거예요.

 

 


FastAPI 요청 흐름, 머릿속 그림으로 그려보면

대충 이런 구조라고 보면 됩니다.

Client (React, Vue, Mobile, Desktop 등) → HTTP request → (Nginx 같은 reverse proxy) → Uvicorn(ASGI server) → FastAPI → Pydantic validation → Storage → Response

중간중간에:

  • middleware가 끼어들 수도 있고
  • dependency가 주입되기도 하고
  • Swagger UI로 바로 테스트도 가능하죠

 

지금은 추상적으로 느껴져도, 직접 만들어보면 금방 감이 옵니다.

 

 


Step 1. 프로젝트 세팅 (Virtual Environment + FastAPI 설치)

빈 폴더 하나 만듭니다.

예시:

  • fastapi-issue-tracker

 

IDE(VS Code 추천)와 terminal을 동시에 열어주세요.

 

 

Virtual Environment 만들기

Mac / Linux:

  • python -m venv .venv
  • source .venv/bin/activate

 

Windows:

  • python -m venv .venv
  • .\.venv\Scripts\activate

 

터미널 앞에 (.venv) 표시가 보이면 성공입니다.

 

 

FastAPI 설치

이번에는 standard extra를 씁니다.

  • pip install "fastapi[standard]"

 

Node 기준으로 보면, Express + 필수 미들웨어 한 번에 설치하는 느낌이라고 보면 돼요.

 

 

 


Step 2. Entry Point 만들기 (main.py)

Node에서 app.js나 server.js 같은 역할을 하는 파일입니다.

여기서 할 일은 단순해요.

  • FastAPI import
  • app 생성
  • 간단한 route 정의

 

 

Health Check route

/health endpoint를 하나 만듭니다.

이런 endpoint는:

  • 서버 살아있는지 확인하기 좋고
  • 배포 후 모니터링에도 유용합니다

 

response는 간단히:

  • { "status": "ok" }

 

FastAPI는 dict를 자동으로 JSON으로 바꿔줍니다.

 

 

서버 실행

  • fastapi dev main.py

 

브라우저에서:

  • http://localhost:8000/health

 

정상이라면 JSON 응답이 보일 거예요.

 

 

Swagger UI

  • http://localhost:8000/docs

 

여기서 FastAPI의 진가가 느껴집니다.

모든 route가 자동으로 문서화되고, Try it out 버튼으로 바로 요청도 날릴 수 있어요. Postman이 따로 필요 없죠.

 

 

 


라우팅 기본 감 잡기 (GET, Path Param, Query, POST)

본격적으로 Issue API 만들기 전에, 패턴 몇 가지만 빠르게 보고 갑니다.

GET route

  • @app.get("/items")
  • list 반환

 

 

Path Parameter

  • /items/{item_id}
  • function argument로 item_id: int

 

Type hint 덕분에 validation도 자동으로 됩니다.

 

 

Query Parameter

  • /items?page=1&limit=10
  • function에 page: int = 1, limit: int = 10

 

 

POST body

Schema 없이 받으면 뭐든 들어옵니다.

그래서 우리가 곧 Pydantic를 쓰는 거죠.

 

 


Step 3. 프로젝트 구조 정리

main.py에 모든 걸 몰아넣는 건 금물입니다.

아래 구조로 갑니다.

  • app/
    • routes/
      • issues.py
    • storage.py
    • schemas.py
    • middleware/
      • timer.py

 

이 구조가 익숙해지면, 프로젝트가 커져도 덜 혼란스러워요.

 

 


Step 4. Issues Router 만들기

FastAPI의 APIRouter는 Express Router랑 거의 같은 개념입니다.

issues.py에서:

  • router = APIRouter(prefix="/api/v1/issues", tags=["issues"])

 

prefix 덕분에 version 관리도 깔끔해집니다.

 

 

main.py에 router 연결

  • app.include_router(issues_router)

 

Swagger 새로고침하면 Issues 섹션이 생깁니다.

이 순간, “아 이제 진짜 API 만든다”라는 느낌이 옵니다.

 

 

 


Step 5. JSON 기반 Storage (storage.py)

Database 대신 JSON 파일을 씁니다.

이유는 단순해요.

  • FastAPI에 집중
  • 불필요한 복잡도 제거

 

load_data() / save_data() 두 함수만 있으면 충분합니다.

실무에서는 물론 DB 쓰셔야죠. 하지만 학습 단계에선 이게 딱 좋아요.

 

 


Step 6. Pydantic Schemas (schemas.py)

여기서 FastAPI가 진짜 빛을 발합니다.

Enum

  • IssueStatus: open / in_progress / closed
  • IssuePriority: low / medium / high

 

허용된 값만 받게 강제합니다.

 

 

IssueCreate

POST 요청용 schema:

  • title
  • description
  • priority (default: medium)

 

status는 서버에서 자동으로 open 설정

 

 

IssueUpdate

PUT 요청용:

  • 모든 필드 Optional

 

일부만 수정 가능하게 만드는 게 포인트입니다.

 

 

IssueOut

response 전용 schema:

  • id
  • title
  • description
  • priority
  • status

 

API contract가 명확해집니다.

 

 


Step 7. CRUD 전부 구현하기

GET /issues

전체 목록 조회

 

 

POST /issues

Issue 생성

  • uuid 생성
  • JSON 저장
  • 201 status

 

 

GET /issues/{id}

단일 Issue 조회

  • 없으면 404

 

 

PUT /issues/{id}

Issue 수정

  • None 아닌 필드만 업데이트

 

 

DELETE /issues/{id}

Issue 삭제

  • 204 No Content

 

이제 진짜 CRUD API 완성입니다.

 

 

 


Step 8. Middleware 추가 (Request Timer)

middleware는 request/response 사이에 끼어드는 로직입니다.

여기서는:

  • request 처리 시간 측정
  • X-Process-Time header로 응답에 추가

 

Swagger에서 header 확인할 수 있습니다.

 

 

 


Step 9. CORS 설정

Frontend랑 domain이 다르면 CORS 에러 납니다.

FastAPI의 CORSMiddleware로 해결합니다.

이번 예제에서는:

  • 모든 origin 허용

 

실제 서비스에서는 domain 제한 필수입니다.

 

 

 


Step 10. requirements.txt 생성

  • pip freeze > requirements.txt

 

배포할 때 필수입니다.

 

 

 


Step 11. Render로 배포

DevOps 깊게 안 파고도 배포 가능합니다.

Start command:

  • uvicorn main:app --host 0.0.0.0 --port $PORT

 

배포 후:

  • /api/v1/issues
  • /docs

 

정상 동작 확인.

 

 

 


다음 단계는?

이 글에서는 기초 체력을 만드는 데 집중했습니다.

다음으로 추천하는 주제는:

  • Authentication (JWT)
  • DB 연동
  • Permission / Role 관리
  • Testing

 

하지만 여기까지 해봤다면, FastAPI가 왜 인기 있는지 체감했을 겁니다.

AI가 코드를 대신 써주는 시대일수록, 이런 구조적인 이해가 더 중요해집니다.

이제 여러분도 FastAPI로 뭔가 하나 제대로 만들어볼 준비가 됐어요.

반응형