FastAPI | 할일 관리 API 만들어보기

Faithful Dev·2025년 6월 10일
0

셀파트너랩스

목록 보기
1/6

며칠 뒤 입사를 앞두고 미리 공부를 해보고자 간단한 할일 관리 API를 만들어봤다.
2월 MS AI School 수료 후 오랜만에,, 거의 4개월 만에 Python을 다시 만져보는 거라 기초부터 차근차근 진행했는데, 생각보다 FastAPI가 정말 직관적이고 사용하기 쉬웠다.


프로젝트 개요

목표: FastAPI 기본 개념 익히기
기간: 하루
기능: 할일 CRUD(생성, 조회, 수정, 삭제)

사용한 기술 스택

  • FastAPI: 메인 웹 프레임워크
  • SQLAlchemy: ORM(데이터베이스 연동)
  • Pydantic: 데이터 검증 및 직렬화
  • SQLite: 데이터베이스(개발용)
  • PyCharm Professional: 개발 환경

프로젝트 구조

todo_api/
├── main.py        # 메인 애플리케이션
├── database.py    # 데이터베이스 설정
├── models.py      # SQLAlchemy 모델
├── schemas.py     # Pydantic 스키마
└── requirements.txt

간단한 구조지만 실제 실무에서도 많이 사용하는 패턴이라고 한다.


학습 내용

FastAPI 기본 구조

from fastapi import FastAPI

app = FastAPI(title="할일 관리 API", version="1.0.0")

@app.get("/")
def read_root():
	return {"message": "Hello FastAPI!"}

Flask보다도 직관적이게 느껴지는 건,, 그 때보다 내가 조금은 성장했기 때문이려나?
아니면 실제 직관적인가.

자동 API 문서화

FastAPI에서 가장 인상 깊었던 기능은 자동 API 문서 생성이었다. 코드만 작성하면 http://localhost:8000/docs에서 바로 Swagger UI를 만들어줌;;
Java에서 Swagger 설정하던 눈물의 시간들이 떠오른다..

타입 힌팅의 중요성

@app.get("/todos/{todo_id}", response_model=schemas.Todo)
def get_todo(todo_id: int, db: Session = Depends(get_db)):
	# ...

타입 힌팅을 제대로 해주면:

  • 자동완성이 훨씬 정확해지고
  • 런타임 에러를 미리 잡을 수 있으며
  • API 문서에 타입 정보가 자동으로 표시된다고 한다.

Pydantic 데이터 검증

class TodoCreate(BaseModel):
	title: str
    description: Optional[str] = None

요청 데이터가 자동으로 검증되고, 잘못된 데이터가 오면 명확한 에러 메시지를 보여준다.


마주친 문제와 해결과정

Java 개발자가 겪는 Python 타입 차이

딱 하나 마주한 에러.

PydanticSchemaGenerationError: Unable to generate pydantic-core schema for <class 'sqlalchemy.sql.sqltypes.Boolean'>

문제: Java에서는 Boolean이 자연스러워서 그대로 사용
해결: Python에서는 소문자 bool을 사용

# ❌ Java 스타일로 작성
class Todo(BaseModel):
    completed: Boolean  # Java처럼 대문자

# ✅ Python 스타일로 수정
class Todo(BaseModel):
    completed: bool  # Python은 소문자

Java에서는 Boolean, String, Integer 같은 래퍼 클래스를 사용하지만,
Python에서는 bool, str, int 같은 기본 타입을 사용한다는 것을 다시 한번 상기하며,,,


PyCharm

몇 년 전에 처음 Python 쓸 때는 VS Code가 훨씬 편했던 것 같은데, Professional 버전이라 그런가 아니면 IntelliJ에 익숙해져서 그런가 PyCharm이 이제는 꽤나 만족스럽다.


구현한 주요 기능들

할일 CRUD API

  • GET /todos - 모든 할일 조회
  • GET /todos/{id} - 특정 할일 조회
  • POST /todos - 새 할일 생성
  • PUT /todos/{id}/complete - 할일 완료 처리
  • DELETE /todos/{id} - 할일 삭제

의존성 주입

Python FastAPI

def get_db():
	db = SessionLocal()
    try:
    	yield db
    finally:
    	db.close()

@app.get("/todos")
def get_todos(db: Session = Depends(get_db)):
	# db는 자동으로 주입됨
    return db.query(Todo).all()

; 없이 들여쓰기로만 구분하는 파이썬 문법에 오랜만에 어색함을 느끼며,,

Java Spring

@Service
public class TodoService {
	@Autowired
    private SessionFactory sessionFactory;
    
    public List<Todo> getTodos() {
    	Session session = sessionFactory.getCurrentSession();
        return session.createQuery("FROM Todo", Todo.class).list();
	}
}

@RestController
public class TodoController {
	@Autowired
    private TodoService todoService;	// 의존성 주입
    
    @GetMapping("/todos")
    public List<Todo> getTodos() {
    	return todoService.getTodos();
	}
}

이렇게 보니까 자바가 진짜 복잡하다는 게 새삼..

주요 차이점

측면Java SpringPython FastAPI
어노테이션@Autowired, @ServiceDepends() 함수
설정XML/Java Config 클래스함수 정의만으로 충분
생명주기 관리Spring Containeryield로 명시적 관리
타입 안정성컴파일 타임 체크런타임 + 타입 힌트

FastAPI의 Depends()는 Spring의 @Autowired와 같은 역할을 한다.
yield를 사용한 리소스 관리가 Python 답게 깔끔하다.


에러 처리

Python FastAPI

from fastapi import HTTPException

@app.get("/todos/{todo_id}")
def get_todo(todo_id: int):
	todo = db.query(Todo).filter(Todo.id == todo_id).first()
    if todo is None:
    	raise HTTPException(status_code=404, detail="할일을 찾을 수 없습니다.")
	return todo

Java Spring

@RestController
public class TodoController {

	@GetMapping("/todos/{id}")
    public ResponseEntity<Todo> getTodo(@PathVariable Long id) {
    	Todo todo = todoService.findById(id);
        if (todo == null) {
        	return ResponseEntity.notFound().build();
		}
        return ResponseEntity.ok(todo);
	}
    
    // 또는 Exception Handler 사용
    @ExceptionHandler(TodoNotFoundException.class)
    public ResponsEntity<ErrorResponse> handleNotFound(TodoNotFoundException ex) {
    	return ResponseEntity.status(404)
        	.body(new ErrorResponse("할일을 찾을 수 없습니다."));
	}
}

주요 차이점

측면Java SpringPython FastAPI
에러발생ResponseEntity 반환 또는 Exception throwHTTPException raise
상태코드ResponseEntity.notFound()status_code=404
에러메시지별도 ErrorResponse 클래스detail 파라미터
글로벌처리@ExceptionHandlerException Handler 함수

FastAPI에서는 Python 예외 처리 방식을 그대로 활용해서 raise HTTPException으로 간단하게 에러를 던질 수 있어서 직관적이었다.


FastAPI의 장점

일단 내가 오늘 경험한 장점으로는

  • 문법이 직관적이고 (이것은 FastAPI의 장점인지, Python의 장점인지, 둘다인지 모르겠으나),
  • 자동 API 문서화, 이거 너무 좋다.

다음 단계

오늘은 다시 Python 감을 찾느라고 기본 CRUD만 구현해봤는데,

  • 사용자 인증 (JWT)
  • 권한 관리
  • 페이지네이션
  • 검색 및 필터링
  • 테스트 코드 작성
  • Docker 컨테이너화

까지 차근차근 입사 전까지 공부해보면 좋겠다.
조금 더 여유가 된다면 웹크롤링까지!


마무리

오랜만에 Python 다시 만져봤는데 너무 재밌다.
잠 안 자고 더 하고 싶은 마음이 들지만,, 컨디션을 관리해야 하므로.

입사하면 실제로 FastAPI를 쓰게 될텐데, 벌써 새로운 공부들이 기대된다 히히 😛

profile
Turning Vision into Reality.

0개의 댓글