반응형

웹 개발 기초와 Django 프레임워크 개요

여러분, Python만 알면 웹 사이트도 뚝딱 만들 수 있다면 믿으시겠어요?
Django는 그걸 가능하게 해주는 도구예요!

 

 

안녕하세요, 여러분~! 😊
혹시 "웹 개발"이라는 말만 들어도 벌써 머리가 복잡해지는 분 계신가요? 저도 처음엔 그랬어요.

HTML, CSS, JavaScript, 서버, 데이터베이스... 어디서부터 시작해야 할지 막막했거든요.

그래서 이 시리즈에서는 여러분이 편안하게 웹 개발의 기초를 익힐 수 있도록, 정말 친절하고 쉽게!

Django라는 프레임워크를 중심으로 하나하나 알려드릴 거예요.

오늘은 그 첫 걸음으로, 웹 개발이 무엇인지, HTTP란 무엇이며, Django는 어떤 역할을 하는지, 그리고 개발을 시작하기 위한 로컬 환경은 어떻게 준비하는지 이야기해볼게요.

마치 요리를 시작하기 전 재료부터 차근히 준비하듯, 개발도 준비가 반이니까요!

 

1. HTTP란 무엇인가요? 🌐

웹 개발을 제대로 이해하려면 가장 먼저 HTTP라는 용어부터 알아야 해요.

HyperText Transfer Protocol의 약자인 HTTP는 인터넷에서 정보를 주고받을 때 사용하는 기본 규칙이에요.

쉽게 말해, 웹 브라우저와 서버가 대화할 때 사용하는 언어죠.

우리가 웹 브라우저에 주소를 입력하면 HTTP 요청(Request)이 발생하고, 서버는 거기에 맞는 HTTP 응답(Response)을 보냅니다.

예를 들어,

여러분이 https://www.google.com에 접속하면 브라우저는 "이 주소에 해당하는 내용을 주세요!"라고 요청하고, 서버는 "여기 있어요!" 하면서 응답을 보내는 거예요.

📋 주요 HTTP 메서드 정리

메서드 설명 예시
GET 데이터를 조회할 때 사용 /articles
POST 새로운 데이터를 생성할 때 사용 /articles (글 작성)
PUT 기존 데이터를 수정할 때 사용 /articles/3 (3번 글 수정)
DELETE 데이터를 삭제할 때 사용 /articles/3 (3번 글 삭제)
  • 클라이언트 = 웹 브라우저, 서버 = 정보를 제공하는 곳
  • HTTP는 이 둘의 소통을 위한 ‘공용 언어’예요
  • 다양한 메서드를 통해 어떤 ‘행동’을 할지 서버에 알려줘요

정리하자면, HTTP는 웹 개발의 기본 중의 기본입니다.

이 개념을 확실히 이해하고 있어야 웹 프레임워크가 하는 일을 자연스럽게 받아들일 수 있어요.

다음 섹션에서는 웹 프레임워크가 도대체 무슨 일을 해주는지도 살펴볼게요.

 

 

2. 웹 프레임워크의 개념과 역할 🧱

웹 개발을 처음 접하는 분들은 "웹 프레임워크"라는 말이 좀 낯설게 느껴질 수 있어요.

웹 프레임워크란 쉽게 말해서, 웹사이트를 만들기 위한 재료와 조리도구가 모두 포함된 요리 세트라고 생각하면 됩니다.

우리가 만약 웹 프레임워크 없이 개발한다면, 요청 처리, URL 연결, 폼 검증, 데이터 저장, 보안, 세션 등 모든 걸 직접 다 만들어야 해요.

마치 라면도 면부터 직접 뽑고, 스프도 만들고, 그릇도 빚는 느낌... 😵‍💫 하지만 프레임워크를 사용하면 이런 반복적인 작업들을 자동화하고 간편화해줍니다.

💡 웹 프레임워크가 하는 일

  • 사용자가 입력한 URL을 어떤 기능과 연결할지 결정해요 (라우팅)
  • 사용자의 입력값을 안전하게 처리해줘요 (폼 검증, 보안 필터)
  • 데이터베이스와 연결해서 정보를 읽고 쓰게 해줘요
  • 사용자가 보는 웹 페이지도 만들어 줘요 (템플릿 렌더링)

✔ 왜 웹 프레임워크를 써야 할까?

  1. 복잡한 웹 기능을 빠르고 쉽게 구현할 수 있어서
  2. 보안, 성능, 유지보수 등 전문가들이 설계한 기능을 그대로 활용할 수 있어서
  3. 문서화와 커뮤니티가 잘 되어 있어서 문제 해결이 쉬워요

이제 왜 웹 프레임워크가 중요한지 감이 오시죠?

Django는 그런 프레임워크 중에서도 아주 강력하고, 쉬우며, 실무에서도 많이 쓰이는 대표적인 녀석이에요. 다음 장에서는 Django가 왜 그렇게 많은 사랑을 받는지 그 매력을 살펴보죠!

 

 

3. Django의 특징과 장점 ✨

Django(장고)는 Python 기반의 웹 프레임워크예요.

"The web framework for perfectionists with deadlines"라는 슬로건처럼, 빠르고 깔끔한 개발을 원하는 사람들에게 안성맞춤이에요. 🧑‍💻

처음 접하면 다소 방대해 보일 수 있지만, 알고 보면 개발자의 귀차니즘을 가장 잘 이해하는 프레임워크랍니다!

💎 Django의 대표적인 장점

특징 설명
빠른 개발 폼, 인증, 관리자 페이지 등 대부분 기능을 기본 제공
보안 XSS, CSRF, SQL Injection 등 웹 보안 이슈에 강함
확장성 다양한 앱을 쉽게 붙여서 서비스 확장이 가능함
관리자 기능 자동으로 생성되는 관리자 페이지는 신의 한 수!

📌 이런 분들에게 강력 추천!

  • 프론트엔드보다 백엔드가 더 궁금한 분
  • 서비스 MVP를 빠르게 만들어보고 싶은 스타트업 창업자
  • Python을 배워봤고 이제 웹을 해보고 싶은 분!

Django는 국내외 수많은 웹사이트에서 실전(!)으로 쓰이고 있어요.

여러분도 곧 Django로 진짜 작동하는 웹 서비스를 만들 수 있을 거예요.

이제 Django가 어떻게 구조화되어 있는지, 그 핵심인 MVT 패턴으로 넘어가 볼까요?

 

 

4. Django의 MVT 아키텍처 이해 🧩

웹 프레임워크마다 나름의 아키텍처 구조를 갖고 있어요.

Django에서는 MVT(Model-View-Template) 패턴을 사용합니다.

이건 흔히 들어본 MVC(Model-View-Controller)와 비슷하면서도 Django만의 방식이 녹아 있어요.

📚 MVT 구성요소 한눈에 보기

구성요소 역할 설명
Model 데이터 구조 설계 DB 테이블과 직접 연결, 데이터 읽고 쓰기 담당
View 비즈니스 로직 요청 처리, 어떤 데이터를 보여줄지 결정
Template 사용자에게 보여질 UI HTML로 데이터를 표현하는 데 사용

📌 Django에서의 흐름 정리

  1. 사용자가 웹사이트에 어떤 요청을 보냅니다 (예: 게시글 목록 보기).
  2. View가 그 요청을 받고, 필요한 데이터를 Model에서 가져옵니다.
  3. 가져온 데이터를 Template에 넘겨서 예쁘게 보여줍니다.

이렇게 역할을 명확히 나눔으로써 개발자는 로직만, 디자이너는 UI만 집중할 수 있어요.

협업도 편하고, 유지보수도 쉬워지는 Django의 큰 장점 중 하나랍니다!

이제 Django의 구조까지 살펴봤으니, 실전 준비를 해볼 차례죠.

다음 파트에서는 여러분의 PC에서 Django 개발을 시작할 수 있도록 Windows 개발 환경을 셋업하는 방법을 알아봅니다!

 

 

5. Windows에서 개발환경 준비하기 🛠️

본격적으로 Django를 사용해서 웹 개발을 하려면, 먼저 내 PC에 개발환경부터 갖춰야 해요.

이번 파트에서는 Windows 기반의 로컬 개발환경을 단계별로 구성하는 법을 알려드릴게요.

🔧 Step-by-Step 개발환경 설정 가이드

  1. Python 설치
  2. 가상환경(venv) 설정
  3. 필수 패키지 설치 (pip 이용)
  4. Django 설치 및 프로젝트 시작

1. Python 설치하기 🐍

공식 사이트에 들어가서 Python 최신 버전을 다운로드하고 설치합니다.

설치 시 "Add Python to PATH" 옵션을 꼭 체크해야 해요!

 

Download Python

The official home of the Python Programming Language

www.python.org


파이썬 설치 관련 내용 확인
https://firstcoding.net/54

 

파이썬 개발환경 구축 완벽 가이드 (2025 최신판)

파이썬 개발환경 구축 완벽 가이드 (2025 최신판)처음 파이썬을 배우려는데, 설치부터 뭐가 이렇게 많아?VSCode? 파이참? 뭐가 뭔지 모르겠다면 이 글 하나면 끝!  안녕하세요 😊요즘 AI 열풍 덕분

firstcoding.net

 

2. 가상환경 만들기 💡

가상환경은 프로젝트마다 독립적인 패키지 공간을 만들어줘요. 아래 명령어를 실행해볼게요.

python -m venv venv
venv\Scripts\activate

성공하면 명령 프롬프트에 (venv)가 붙어요.

 

가상환경에 대해 좀더 알아보실 분들은 아래 포스트를 참고해주세요

https://firstcoding.net/74

 

파이썬 가상환경(venv, virtualenv)으로 프로젝트 환경을 깔끔하게 관리하는 법

파이썬 가상환경(venv, virtualenv)으로 프로젝트 환경을 깔끔하게 관리하는 법프로젝트마다 패키지 버전이 달라서 자꾸 충돌난다면? 파이썬 가상환경으로 환경관리를 시작해보세요! 🧪  안녕하

firstcoding.net

 

이제 여기서 Django를 설치하면 됩니다!

3. Django 설치 및 프로젝트 시작 🚀

pip install django
django-admin startproject mysite
cd mysite
python manage.py runserver

위 명령어까지 완료했다면 127.0.0.1:8000 주소로 접속해보세요!

Django 환영 페이지가 나온다면 성공이에요! 🎉

여러분은 지금 Django 웹 개발의 첫 발을 디디셨어요.

앞으로 이 환경에서 앱을 만들고, 데이터베이스를 연결하고, 멋진 서비스를 구현하게 될 거예요!

 

 

6. Python 설치와 가상환경 설정 ⚙️

앞선 STEP에서 간단하게 개발환경을 구성해봤다면, 이번에는 조금 더 자세히 Python 설치와 가상환경 설정에 대해 알아보겠습니다. 특히 여러 프로젝트를 동시에 개발하려면 가상환경을 잘 활용하는 습관이 정말 중요해요.

📌 Python 설치 팁

  • 설치 중 반드시 “Add Python to PATH” 체크!
  • 버전 충돌 방지를 위해 최신 버전 사용 권장

설치 후 명령 프롬프트에서 다음 명령어로 확인해볼 수 있어요.

python --version
pip --version

🌱 가상환경(venv) 개념 다시 보기

가상환경은 말 그대로 프로젝트마다 독립적인 Python 공간이에요.

예를 들어,

블로그 웹사이트에선 Django 4.2 버전을 쓰고, 쇼핑몰 웹사이트에선 3.2 버전을 쓸 수도 있어요.

이런 걸 가능하게 해주는 게 바로 가상환경입니다.

✔ 가상환경 관리 명령어

명령어 설명
python -m venv venv 가상환경 생성
venv\Scripts\activate 가상환경 활성화 (Windows)
deactivate 가상환경 종료

📎 실전 꿀팁

  • Visual Studio Code를 쓰면 터미널에서 바로 가상환경을 인식해줘요!
  • requirements.txt 파일을 만들어 두면 나중에 패키지 설치가 훨씬 쉬워요.

지금까지 Python 설치와 가상환경 설정에 대해 배워봤어요.

이제 여러분은 Django 개발을 위한 기초 체력을 모두 갖췄다고 볼 수 있죠.

그럼 이제, 이 여정을 마무리하면서 여러분이 앞으로 어떻게 시작하면 좋을지 정리해볼게요!

 

 

🧩 이제 Django 세계로 출발해볼까요?

여기까지 따라오셨다면 정말 수고 많으셨어요!

HTTP의 기본 구조부터 Django의 매력, MVT 패턴, 그리고 개발환경 설정까지 웹 개발을 시작하는 데 꼭 필요한 기초를 차근차근 다졌습니다. 👏

이제 여러분은 개발자 노트북을 열고, Django로 나만의 웹 서비스를 만들 준비가 된 셈이죠.

"아직 잘 모르겠어요..."라는 생각이 드시더라도 괜찮아요.

개발은 해보면서 익히는 것이니까요.

 

다음 글부터는 Django 프로젝트를 하나씩 만들어보면서 실습 중심으로 배워볼 거예요.

"왜 이렇게 동작하지?"라는 의문이 들면 이 글로 다시 돌아와 주세요.

기초는 늘 탄탄하게, 다시 반복할수록 더 잘 보이거든요 😉

 

그럼 우리 다음 글에서는 Django 프로젝트를 직접 만드는 방법으로 이어가 볼게요.

같이 실습하면서 진짜 서비스를 만들 준비되셨죠? 🎯

반응형
반응형

파이썬 FastAPI 실전 프로젝트 구현 (2) – 기능 보완 및 마무리

여러분, 프로젝트 마무리할 때 뭔가 찝찝하게 끝낸 적 있으시죠?
이번에는 FastAPI로 만든 API를 제대로 다듬고,
진짜 ‘완성된’ 느낌을 만들어봐요!

 

 

안녕하세요, 개발자 여러분 😊

드디어 FastAPI 실전 프로젝트의 마지막 단계에 도달했습니다.

앞서 API를 설계하고 기본적인 CRUD 기능을 구현했지만, 사실 프로젝트가 ‘완성됐다’고 말하기 위해서는 몇 가지 마무리 작업이 꼭 필요하죠.

예를 들어 빠진 기능을 채우거나, 리팩토링을 통해 코드 품질을 끌어올리고, 전체 테스트를 통해 문제가 없는지 꼼꼼히 검증하는 과정 말이에요.

이번 글에서는 Update/Delete API 구현, 리팩토링, 테스트 마무리, 추가 기능 구현까지 포함해서, 진짜 실전에 가까운 프로젝트 완성 과정을 함께 해볼 거예요.

이제 진짜 개발자 포트폴리오에 올릴 수 있는 API를 만들어볼 준비되셨나요? 😎 그럼 시작해볼게요!

 

1. CRUD 기능 보완: Update/Delete 엔드포인트 구현 🛠️

1.1 글(Post) 및 할일(Todo) 수정 API 구현

이제 남은 CRUD 기능 중 '수정(Update)' 엔드포인트부터 완성해볼 차례입니다.

블로그 API와 Todo API 모두에 해당하는 기능으로, RESTful한 방식에 따라 PUT 메서드를 사용합니다.

 

FastAPI에서는 @router.put("/posts/{id}") 형식으로 경로를 선언하고, 입력 데이터는 schemas.PostUpdate 같은 Pydantic 모델을 사용해 받습니다.

 

- 수정 대상이 존재하지 않으면 404 Not Found
- 성공 시에는 수정된 객체를 JSON으로 반환
- 인증 기능이 있다면 작성자만 수정 가능하게 조건을 걸 수 있음 (지금은 생략)

예시 코드

@router.put("/posts/{id}")
def update_post(id: int, post_update: PostUpdate, db: Session = Depends(get_db)):
    post = db.query(Post).filter(Post.id == id).first()
    if not post:
        raise HTTPException(status_code=404, detail="Post not found")
    post.title = post_update.title
    post.content = post_update.content
    db.commit()
    db.refresh(post)
    return post

1.2 삭제(Delete) API 구현

삭제 기능은 프로젝트의 정돈을 위해 반드시 필요한 부분이에요.

블로그의 경우 글 삭제, Todo의 경우 할일 삭제가 이에 해당합니다.

완전 삭제 방식으로 구현하되, 보안이나 감사 로그가 필요한 경우에는 Soft Delete 방식도 고민해볼 수 있어요.

예시 코드

@router.delete("/todos/{id}", status_code=204)
def delete_todo(id: int, db: Session = Depends(get_db)):
    todo = db.query(Todo).filter(Todo.id == id).first()
    if not todo:
        raise HTTPException(status_code=404, detail="Todo not found")
    db.delete(todo)
    db.commit()
    return Response(status_code=204)

1.3 마무리 요약

  • PUT 메서드로 수정 API를 추가한다.
  • DELETE 메서드로 삭제 API를 완성한다.
  • 없는 리소스에 접근 시 404 예외 처리를 꼼꼼히 해준다.

이제 CRUD의 4가지 기본 기능이 완성됐습니다.

이 다음은 조금 더 재미있는(?) 추가 기능 구현 시간입니다!

 

 

2. 주제별 추가 기능과 쿼리 개선 🎯

2.1 블로그 API – 사용자별 글 목록 및 검색 기능

블로그 API에선 기본적인 CRUD 외에도, 사용자별 글 목록이나 검색 기능처럼 실전에서 많이 쓰는 기능을 추가해보면 실력이 쑥쑥 자랍니다.

  • GET /users/{user_id}/posts – 특정 유저가 작성한 글만 필터링
  • GET /posts?search=키워드 – 제목/내용에 포함된 키워드로 검색

쿼리 필터 예시

@router.get("/posts")
def list_posts(search: str = None, db: Session = Depends(get_db)):
    query = db.query(Post)
    if search:
        query = query.filter(Post.title.contains(search))
    return query.all()

2.2 Todo API – 완료 여부 필터링 및 정렬

Todo API에선 할 일의 완료 상태우선순위 정렬 기능을 추가하면 사용성이 훨씬 높아져요.

  • GET /todos?completed=true – 완료된 항목만 필터링
  • GET /todos?sort=priority – 우선순위 오름차순 정렬

정렬 필터 예시

@router.get("/todos")
def get_todos(completed: bool = None, sort: str = None, db: Session = Depends(get_db)):
    query = db.query(Todo)
    if completed is not None:
        query = query.filter(Todo.done == completed)
    if sort == "priority":
        query = query.order_by(Todo.priority.asc())
    return query.all()

2.3 마무리 팁 💡

이런 기능은 구현해보면 어렵지 않지만, 실제 API 사용 경험을 엄청나게 향상시켜줍니다.

쿼리 파라미터동적 필터링은 FastAPI와 SQLAlchemy를 익히는 데 정말 좋은 연습이 돼요!

 

꼭 필요한 핵심 기능 외에도 사용자가 편리하게 쓸 수 있는 부가 기능 몇 개만 추가해도, 프로젝트의 깊이가 확 달라진다는 거 잊지 마세요 😉

 

 

3. 코드 리팩토링과 공통 모듈 정리 📦

3.1 중복 로직 정리: get_object_or_404

FastAPI로 프로젝트를 하다 보면, 가장 자주 반복되는 패턴 중 하나가 바로 이거예요.

query.first()로 객체를 가져오고 없으면 HTTPException(404)을 던지는 코드!

매번 반복하지 말고, 다음과 같이 공통 헬퍼 함수로 만들어두면 가독성과 유지보수성이 확 올라갑니다.

def get_object_or_404(query, model_name: str = "Object"):
    obj = query.first()
    if not obj:
        raise HTTPException(status_code=404, detail=f"{model_name} not found")
    return obj

 

이제 이렇게 쓰면 됩니다:

post = get_object_or_404(db.query(Post).filter(Post.id == id), "Post")

3.2 인증/권한 검사 공통화

만약 로그인 인증 기능이 있다면, API마다 인증 정보를 검사하는 코드도 반복됩니다.

FastAPI는 Depends()를 이용해 공통 처리할 수 있어요.

def get_current_user(token: str = Depends(oauth2_scheme)):
    payload = decode_token(token)
    user = db.query(User).filter(User.id == payload["sub"]).first()
    if not user:
        raise HTTPException(status_code=401, detail="Invalid credentials")
    return user

 

라우터에서는 이렇게 간단히 호출하면 되죠:

@router.get("/me/posts")
def my_posts(current_user: User = Depends(get_current_user)):
    return current_user.posts

3.3 Swagger 문서화 향상

Swagger UI를 더 보기 좋게 꾸미고 싶다면, Pydantic 모델에 description 필드를 넣는 게 좋아요.

이게 곧 API 문서가 되거든요.

class PostCreate(BaseModel):
    title: str = Field(..., description="게시글 제목")
    content: str = Field(..., description="게시글 본문")

 

이렇게 하면 Swagger에서 각 필드 설명이 뜨고, 사용자나 동료 개발자에게도 친절한 API가 됩니다. 🧾

3.4 디버그 흔적 제거

그리고 가장 중요한 마무리 습관!

print 같은 디버깅 코드는 모두 제거해주세요.

콘솔에 찍히는 메시지는 실서비스에서 보안 위험이 될 수도 있고, 로그 관리도 어려워지니까요.

  • print() 제거
  • 테스트용 더미 코드 제거

깔끔한 코드는 실력의 증거입니다.

동료도, 미래의 나도 기뻐할 거예요. 😉

 

 

4. Swagger 기반 수동 테스트 🧪

4.1 Swagger UI에서 테스트 시나리오 따라가기

FastAPI의 강력한 무기 중 하나는 바로 자동 생성 API 문서, Swagger UI죠!

개발한 모든 엔드포인트를 웹 UI로 손쉽게 테스트할 수 있다는 점에서, 이건 정말 필수 기능이에요.

 

테스트를 시작할 땐, 가능한 실제 사용자 시나리오 기반으로 순서대로 실행해보는 게 좋아요.

예를 들어:

  1. 1️⃣ 사용자 생성 (POST /users)
  2. 2️⃣ 로그인 (만약 구현했다면)
  3. 3️⃣ 글 or 할일 생성
  4. 4️⃣ 목록 조회
  5. 5️⃣ 글/할일 수정
  6. 6️⃣ 삭제 요청
  7. 7️⃣ 삭제 후 목록 재조회

4.2 예외 상황도 꼭 테스트해보자!

정상 흐름만 테스트하면 부족해요.

진짜 완성도 높은 API는 경계 상황까지 잘 처리하는 경우죠.

 

꼭 체크해야 할 케이스 리스트 ✔️

  • 존재하지 않는 ID로 요청했을 때 → 404 Not Found 잘 반환되는가?
  • 필수 값이 빠진 입력 → 422 Unprocessable Entity 나오는가?
  • 중복된 값 입력 → 에러 메시지가 친절한가?

이런 테스트는 Swagger UI에서 직접 해볼 수도 있지만, Postman이나 curl 같은 도구로 해보는 것도 좋은 연습이에요.

다양한 환경에서 동일한 API가 잘 작동하는지 확인할 수 있거든요.

4.3 마무리하며

직접 테스트해보면서 API 동작을 확인하는 건, 말 그대로 ‘현장감 있는 검증’입니다.

직접 손으로 다뤄보는 만큼, 놓쳤던 버그도 쉽게 발견되죠.

 

이제 우리 프로젝트도 한 단계 성숙해졌네요.

다음은 자동화 테스트로 더 철저하게 완성도를 높이는 시간입니다! 😎

 

 

5. pytest를 활용한 자동화 테스트 🔍

5.1 pytest 기본 구조와 테스트 함수 작성

FastAPI 프로젝트에선 pytest를 사용해 자동화 테스트를 작성하는 게 표준입니다.

기능 하나하나를 수동으로 확인할 수는 없으니, 테스트 코드를 작성해두면 나중에 기능을 수정하거나 리팩토링해도 안정성을 체크할 수 있어요.

예시 테스트 코드

from fastapi.testclient import TestClient
from app.main import app

client = TestClient(app)

def test_create_todo():
    response = client.post("/todos", json={
        "title": "테스트 할일",
        "description": "자동화 테스트용"
    })
    assert response.status_code == 200
    assert response.json()["title"] == "테스트 할일"

 

단순해 보이지만, POST 요청 → 응답 확인 → 예상 결과 비교까지 핵심 흐름이 모두 담겨 있어요.

5.2 테스트 커버리지 넓히기

단일 테스트로는 부족하죠.

아래 항목들을 테스트 목록에 꼭 포함시켜보세요:

  • 목록 조회 (GET) 응답이 올바른지
  • 수정/삭제 요청 시 상태코드 확인
  • 없는 ID로 요청 시 404 테스트

5.3 테스트 실행 및 자동화 팁

터미널에서 다음 명령어를 입력하면 테스트가 실행됩니다.

pytest tests/

 

Tip: GitHub Actions 또는 GitLab CI와 연동하면 커밋할 때마다 자동으로 테스트가 돌아가요.

       이것만 잘해도 실무에선 ‘코드 퀄리티 보장’으로 인정받습니다.

5.4 테스트 작성 못했다면?

사실 시간이 부족하거나 학습이 익숙하지 않다면, 모든 자동화 테스트를 작성하는 건 쉽지 않아요.

그럴 땐 수동 테스트와 로그 확인으로 충분히 대체 가능합니다.

 

하지만 이번 프로젝트가 끝나고 나면 꼭 pytest + FastAPI 조합으로 테스트를 구성해보세요.

다음 프로젝트에서는 코드 품질의 자신감이 달라질 거예요!

 

 

6. 프로젝트 마무리 및 다음 단계 제안 🚀

6.1 FastAPI 프로젝트 완성 축하합니다! 🎉

정말 고생 많으셨어요!

지금까지 FastAPI + SQLAlchemy를 활용해서 REST API를 설계하고, 구현하고, 테스트하고, 마무리까지 해냈습니다.

처음엔 생소하고 어렵게 느껴졌던 코드들도 이제는 익숙하게 다뤘을 거예요. 👏👏👏

6.2 포트폴리오로 남기는 법 💼

  • GitHub에 코드 업로드: 기능별 커밋 기록은 매우 큰 가산점!
  • README.md 작성: 사용 방법, 기능 목록, 설치 방법 포함하면 👍
  • 시연 영상 or 이미지 첨부: 블로그나 유튜브 링크도 함께!

6.3 다음에 도전해볼 것들 ✨

이제 진짜 FastAPI를 익힌 셈이니까요, 다음 단계로 이런 걸 시도해보면 좋습니다:

  • JWT 인증과 OAuth2 로그인 적용 (보안 강화)
  • Docker로 서비스 배포 준비
  • 프론트엔드 연동 (React, Vue 등으로 UI 구현)

6.4 참고 자료 📚

학습을 계속 이어가고 싶다면, 아래 자료들을 추천합니다:

FastAPI는 앞으로도 계속 성장할 프레임워크입니다.

꾸준히 공식 문서를 체크하고, 오픈소스 프로젝트에 기여해보는 것도 추천드려요!

 

 

마무리 🎁

지금까지 우리는 FastAPI를 활용한 실전 프로젝트를 단계별로 구축해왔고, 그 마지막 단계인 기능 보완과 테스트, 리팩토링까지 성공적으로 마무리했습니다.

이 과정을 통해 FastAPI의 기본 구조뿐 아니라 RESTful API 설계, ORM 연동, 예외 처리, 테스트 자동화에 이르기까지 백엔드 개발에서 꼭 필요한 스킬들을 하나씩 익혔어요.

특히 이번 프로젝트는 단순히 작동만 되는 코드가 아닌, 실제 서비스에 가까운 형태로 구현했다는 점에서 큰 의미가 있습니다.

지금까지 작성한 코드들은 포트폴리오로 활용할 수 있을 만큼 구조적이고 완성도가 높아졌습니다.

여기까지 따라오셨다면 정말 큰 박수를 드리고 싶어요. 👏👏👏

 

앞으로는 이 기반 위에 인증, 배포, 프론트엔드 연동 등 더 넓은 분야로 확장해보세요.

그리고 중요한 건 꾸준히 연습하고, 실제 프로젝트에 응용해보는 겁니다.

이제 여러분도 자신 있게 말할 수 있어요.

"FastAPI로 백엔드 개발할 줄 압니다!" 💪

🎯 이 글의 핵심 요약

  • ✅ CRUD 완성: Update/Delete 엔드포인트 구현
  • ✅ 사용자 중심 필터링, 검색 등 추가 기능
  • ✅ 공통 함수 및 인증 구조 리팩토링
  • ✅ Swagger를 통한 수동 테스트
  • ✅ pytest 기반 자동화 테스트 도입
  • ✅ 실무형 프로젝트 구조와 문서화

 

여기서 끝나지 않아요.

지금까지 쌓은 지식을 바탕으로 더 멋진 API, 더 나은 백엔드 시스템을 계속 만들어가시길 바랍니다.

여러분의 여정을 응원합니다! 🚀

반응형
반응형

파이썬 FastAPI 실전 프로젝트 (1) – 블로그 API/Todo API 설계 및 구현 

단순한 예제만으로는 실력이 늘지 않아요.
진짜로 내가 만든 FastAPI 서비스,
지금부터 직접 설계하고 구현해보는 시간입니다!

 

 

안녕하세요 여러분 😊

드디어 지금까지 배운 FastAPI 내용을 바탕으로 직접 프로젝트를 시작할 차례입니다!

이제는 단순한 이론이나 짧은 실습이 아니라, 사용자 관리부터 게시글 또는 할일 등록까지 기능이 갖춰진 나만의 API 서비스를 만들게 될 거예요.

이번 실전 프로젝트는 두 가지 주제 중 하나를 선택해서 진행할 수 있어요:

1) 블로그 API 또는 2) Todo 관리 API.

둘 다 FastAPI + SQLAlchemy를 활용해 RESTful 백엔드 API를 직접 설계하고 구현하는 경험을 하게 됩니다.

각 기능별 CRUD 구현뿐 아니라, 모델 설계, 프로젝트 구조 구성, 예외 처리, 테스트까지 고려한 구조로 만들어볼 거예요.

지금부터 7일차 여정을 함께 출발해볼까요? 🚀

 

1. 최종 프로젝트 개요 및 설계 🧭

여러분, 여기까지 따라오시느라 정말 고생 많으셨어요. 😊

지금까지 FastAPI의 기본적인 사용법, SQLAlchemy 연동, 라우팅, Pydantic 모델링, 예외 처리 등을 하나씩 차근차근 배워오셨죠?

이제는 그 모든 퍼즐을 모아서 직접 하나의 프로젝트로 완성해볼 차례입니다.

1.1 프로젝트 주제와 목표 🎯

이번 프로젝트에서는 두 가지 주제 중 하나를 선택할 수 있어요:

  • 블로그 API: 사용자 인증, 글 작성, 글 목록 조회, 상세 보기, 댓글 작성/삭제, 태그 기능 포함
  • Todo API: 사용자 생성, 할일 CRUD, 우선순위 설정, 완료 상태 필터링 기능 제공

물론 두 프로젝트 모두 공통적으로 사용자 모델, 데이터베이스 연동, CRUD 기능이 핵심이 되며, 선택한 주제에 따라 약간의 기능 차이가 있을 뿐입니다.

1.2 이번 실습의 핵심 목표 🧩

  1. FastAPI의 주요 기능을 실제 API에 적용
  2. SQLAlchemy를 통한 모델 정의와 DB 연동 실습
  3. Pydantic을 활용한 데이터 검증
  4. 기본적인 예외 처리와 테스트 코드 작성
  5. REST API의 CRUD 기능 전반 구현

즉, 이번 실습의 핵심은 단순히 동작하는 코드를 작성하는 것이 아니라, 정리된 구조와 유지보수 가능한 코드를 직접 설계하고 구현하는 것입니다.

실무에서 백엔드를 처음 시작할 때 어떤 흐름으로 개발을 진행해야 하는지, 그 뼈대를 이번 실습을 통해 직접 익히게 될 거예요.

 

이제 다음 단계로 넘어가서, 구체적인 데이터 모델을 어떻게 설계할지 알아보겠습니다.

 

 

2. 데이터 모델 설계 📐

서비스를 만들기 전, 가장 먼저 해야 할 일은 데이터 구조를 어떻게 설계할 것인가입니다.

바로 모델링이죠.

데이터베이스 구조가 깔끔하게 설계되어야 API도 명확하게 작동하고, 유지보수도 수월해집니다.

이번엔 선택한 프로젝트 유형에 따라 각기 다른 모델을 설계하게 됩니다.

2.1 블로그 API 모델 예시 ✍️

블로그 API를 선택한 경우, 보통 다음과 같은 세 가지 모델이 필요해요:

모델 필드 설명
User id, username, email, hashed_password 회원 정보 (비밀번호는 해싱 처리)
Post id, title, content, created_at, author_id 글 제목, 본문, 작성 시간 및 작성자
Comment id, content, created_at, post_id, author_id 댓글 내용과 작성자, 연결된 게시글

여기서 중요한 건 외래키 관계입니다.

Post와 Comment는 모두 User와 연결되고, Comment는 Post에도 연결되죠.

SQLAlchemy에서는 ForeignKeyrelationship으로 이를 구현할 수 있어요.

2.2 Todo API 모델 예시 ✅

Todo 프로젝트는 더 단순합니다. 모델은 아래 두 개만 필요하죠.

모델 필드 설명
User id, username 사용자 이름 (unique 설정 권장)
Todo id, title, description, priority, completed, user_id 할일 제목, 설명, 우선순위, 완료 여부, 사용자

💡 모델 설계 팁

  • 문자열 길이 제한을 String(length)으로 명확하게 지정하세요.
  • nullable=False는 필수 필드에 반드시 지정해줘야 합니다.
  • 고유성이 필요한 필드는 unique=True로 중복 방지!

이제 데이터 모델이 명확하게 정리되었으니,

다음 단계는 실제 프로젝트 디렉토리 구조를 만들고 빈 틀을 잡아보는 것입니다.

프로젝트가 커질수록 구조가 중요해지니까요.

계속해서 다음 단계에서 프로젝트 뼈대를 만들어볼게요!

 

 

3. 프로젝트 구조 뼈대 만들기 🧱

FastAPI 프로젝트를 시작할 때 가장 먼저 해야 할 일은 전체 폴더 구조를 체계적으로 잡는 것이에요.

한 파일 안에 모든 코드를 몰아넣는 방식은 소규모 예제에선 괜찮지만, 프로젝트가 커지면 유지보수가 거의 불가능하죠.

이번 프로젝트에서는 아래와 같은 구조를 기준으로 설계를 시작합니다.

3.1 기본 디렉토리 구조

myapi/
├── main.py               # FastAPI 앱 실행 진입점
├── models.py             # SQLAlchemy ORM 모델 정의
├── schemas.py            # Pydantic 데이터 모델 정의
├── database.py           # DB 설정 (engine, session, get_db)
├── routers/
│   ├── users.py          # 사용자 관련 라우터
│   └── posts.py          # 블로그 글 관련 라우터 (or todos.py)
└── __init__.py           # 패키지 초기화 파일 (선택 사항)

✅ 핵심 원칙은 다음과 같아요:

  • 각 기능을 독립적인 모듈로 구성 → 관심사의 분리(SOC) 원칙 준수
  • DB 관련 코드는 database.py에 모아서 일원화
  • Pydantic 모델은 schemas.py에서 관리하여 API 스키마 명확화

🛠 main.py 기본 틀

from fastapi import FastAPI
from routers import users, posts  # 또는 todos

app = FastAPI()

app.include_router(users.router)
app.include_router(posts.router)

🔌 database.py 기본 구성

from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker

DATABASE_URL = "sqlite:///./test.db"

engine = create_engine(DATABASE_URL, connect_args={"check_same_thread": False})
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)

Base = declarative_base()

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

이처럼 프로젝트 초기 구조를 잘 설계하면, 나중에 기능을 추가할 때도 훨씬 덜 헤매고 유지보수가 쉬워집니다.

앞으로 posts.py, todos.py, comments.py 등을 기능별로 확장할 수 있도록 유연한 구조로 시작하세요!

 

이제 구조가 준비되었으니, 본격적으로 사용자 기능부터 구현해볼까요?

다음 섹션에서는 사용자 생성과 조회를 구현하면서 실전 코딩을 시작합니다!

 

 

4. 사용자 기능 구현 🔐

프로젝트에서 사용자(User)는 모든 기능의 출발점이에요.

할일이든 게시글이든 결국 ‘누가 작성했는지’가 중요하니까요.

이번 단계에서는 사용자 등록(POST)과 조회(GET) API를 구현합니다.

이 두 기능만 제대로 작동해도 프로젝트의 절반은 성공한 셈이에요!

4.1 Pydantic 스키마 만들기

우선 schemas.py에 사용자 관련 데이터 구조를 정의합니다:

from pydantic import BaseModel, EmailStr

class UserBase(BaseModel):
    username: str
    email: EmailStr

class UserCreate(UserBase):
    password: str

class User(UserBase):
    id: int

    class Config:
        orm_mode = True

4.2 SQLAlchemy 모델 정의

models.py에는 사용자 모델을 다음과 같이 정의해요:

from sqlalchemy import Column, Integer, String
from database import Base

class User(Base):
    __tablename__ = "users"

    id = Column(Integer, primary_key=True, index=True)
    username = Column(String(30), unique=True, nullable=False)
    email = Column(String(100), unique=True, nullable=False)
    hashed_password = Column(String(128), nullable=False)

💡 비밀번호는 평문 저장 No!

여기선 해시 없이 저장하겠지만, 실무에서는 꼭 bcrypt 같은 해싱 알고리즘을 사용해야 해요.

4.3 사용자 생성 API

# routers/users.py
from fastapi import APIRouter, HTTPException, Depends
from sqlalchemy.orm import Session
from database import get_db
import models, schemas

router = APIRouter(prefix="/users", tags=["Users"])

@router.post("/", response_model=schemas.User)
def create_user(user: schemas.UserCreate, db: Session = Depends(get_db)):
    existing_user = db.query(models.User).filter(
        (models.User.username == user.username) | (models.User.email == user.email)
    ).first()
    if existing_user:
        raise HTTPException(status_code=400, detail="Username or email already exists")

    db_user = models.User(
        username=user.username,
        email=user.email,
        hashed_password=user.password  # 실무에서는 해싱 필수!
    )
    db.add(db_user)
    db.commit()
    db.refresh(db_user)
    return db_user

4.4 사용자 조회 API

@router.get("/{user_id}", response_model=schemas.User)
def read_user(user_id: int, db: Session = Depends(get_db)):
    user = db.query(models.User).filter(models.User.id == user_id).first()
    if user is None:
        raise HTTPException(status_code=404, detail="User not found")
    return user

🧪 테스트 팁

  • Swagger UI(/docs)에서 POST → 바로 GET으로 테스트 가능!
  • uvicorn main:app --reload로 서버 실행하세요.

이제 사용자가 등록되고 조회되는 API가 완성되었습니다!

이 데이터를 기반으로 다음 단계에서는 본격적인 게시글(Post) 혹은 할일(Todo) 기능을 구현해보겠습니다.

 

 

5. 글쓰기 or 할일 등록 기능 구현 ✏️

이제 사용자 기능이 잘 작동하는 걸 확인했다면, 다음은 본 서비스의 중심 기능인 게시글(Post) 또는 할일(Todo)을 구현할 차례입니다.

블로그 API를 선택한 분은 글쓰기 기능을, Todo API를 선택한 분은 할일 등록 기능부터 차근차근 구현해보면 됩니다.

5.1 블로그 글쓰기 기능 (POST /posts/) 📝

# schemas.py
from datetime import datetime

class PostBase(BaseModel):
    title: str
    content: str

class PostCreate(PostBase):
    author_id: int

class Post(PostBase):
    id: int
    created_at: datetime
    author_id: int

    class Config:
        orm_mode = True
# models.py
from sqlalchemy import Column, Integer, String, ForeignKey, DateTime
from sqlalchemy.orm import relationship
from datetime import datetime

class Post(Base):
    __tablename__ = "posts"

    id = Column(Integer, primary_key=True, index=True)
    title = Column(String(100), nullable=False)
    content = Column(String, nullable=False)
    created_at = Column(DateTime, default=datetime.utcnow)
    author_id = Column(Integer, ForeignKey("users.id"), nullable=False)

    author = relationship("User", backref="posts")
# routers/posts.py
@router.post("/", response_model=schemas.Post)
def create_post(post: schemas.PostCreate, db: Session = Depends(get_db)):
    db_post = models.Post(
        title=post.title,
        content=post.content,
        author_id=post.author_id
    )
    db.add(db_post)
    db.commit()
    db.refresh(db_post)
    return db_post

5.2 글 목록 및 상세 조회 (GET /posts/, /posts/{id}) 📚

@router.get("/", response_model=List[schemas.Post])
def read_posts(skip: int = 0, limit: int = 10, db: Session = Depends(get_db)):
    posts = db.query(models.Post).offset(skip).limit(limit).all()
    return posts

@router.get("/{post_id}", response_model=schemas.Post)
def read_post(post_id: int, db: Session = Depends(get_db)):
    post = db.query(models.Post).filter(models.Post.id == post_id).first()
    if not post:
        raise HTTPException(status_code=404, detail="Post not found")
    return post

쿼리 파라미터로 skiplimit을 받아 간단한 페이징 기능도 적용해봤어요.

물론 실제 서비스라면 페이지 번호, 정렬 기준 등 더 다양한 필터가 필요하겠지만, 지금은 핵심 흐름만 익히는 게 중요합니다.

5.3 할일 등록 기능 (POST /todos/) ✅

# schemas.py
class TodoBase(BaseModel):
    title: str
    description: str

class TodoCreate(TodoBase):
    user_id: int

class Todo(TodoBase):
    id: int
    completed: bool
    priority: int

    class Config:
        orm_mode = True
# models.py
class Todo(Base):
    __tablename__ = "todos"

    id = Column(Integer, primary_key=True, index=True)
    title = Column(String(100), nullable=False)
    description = Column(String, nullable=False)
    completed = Column(Boolean, default=False)
    priority = Column(Integer, default=1)
    user_id = Column(Integer, ForeignKey("users.id"))

    user = relationship("User", backref="todos")
# routers/todos.py
@router.post("/", response_model=schemas.Todo)
def create_todo(todo: schemas.TodoCreate, db: Session = Depends(get_db)):
    db_todo = models.Todo(
        title=todo.title,
        description=todo.description,
        user_id=todo.user_id
    )
    db.add(db_todo)
    db.commit()
    db.refresh(db_todo)
    return db_todo

5.4 할일 목록 및 상세 조회 (GET /todos/, /todos/{id}) 📋

@router.get("/", response_model=List[schemas.Todo])
def read_todos(db: Session = Depends(get_db)):
    return db.query(models.Todo).all()

@router.get("/{todo_id}", response_model=schemas.Todo)
def read_todo(todo_id: int, db: Session = Depends(get_db)):
    todo = db.query(models.Todo).filter(models.Todo.id == todo_id).first()
    if not todo:
        raise HTTPException(status_code=404, detail="Todo not found")
    return todo

여기까지 완성되면 사용자 - 게시글, 또는 사용자 - 할일 구조의 기본 CRUD의 반 이상이 만들어진 셈입니다. 다음 단계에선 이 모든 기능들이 실제로 잘 작동하는지 테스트해보는 실습을 진행할 거예요!

 

 

6. 서버 실행 및 결과 테스트 ⚙️

이제 우리 프로젝트의 기본 기능은 모두 구현이 끝났습니다!

이제는 서버를 실행해보고, 실제 요청을 보내보며 테스트하는 단계입니다.

FastAPI의 가장 큰 장점 중 하나가 바로 Swagger UI를 통한 인터랙티브 테스트 환경이죠.

하나씩 점검하면서 내가 만든 API가 잘 작동하는지 직접 확인해봅시다.

6.1 서버 실행하기

uvicorn main:app --reload

이 명령어로 로컬 서버를 실행하면 http://127.0.0.1:8000/docs 에서 자동 생성된 Swagger 문서에 접속할 수 있습니다.

이제 각 API 기능을 직접 클릭해보며 테스트해볼 수 있어요.

6.2 주요 테스트 시나리오 🧪

  • POST /users/ : 사용자 등록 요청 → 성공 시 200 반환 및 ID 확인
  • GET /users/{id} : 등록한 사용자 조회 → 사용자 정보 반환
  • POST /posts/ 또는 /todos/ : 글 또는 할일 등록
  • GET /posts/ 또는 /todos/ : 전체 목록 확인
  • GET /posts/{id} 또는 /todos/{id} : 상세 페이지 확인

🚨 자주 발생하는 오류

  • IntegrityError: 이미 존재하는 username 또는 email → 400 예외 처리 필요
  • AttributeError: 'dict' object has no attribute → Pydantic 모델에 orm_mode = True 빠짐

6.3 마무리 점검 리스트 ✅

항목 확인 여부
DB 모델 생성 완료
Pydantic 스키마 정의
CRUD API 작동 확인
Swagger UI 테스트

축하합니다! 여기까지 완성했다면 여러분은 이제 FastAPI 기반의 실제 동작하는 백엔드 서비스를 손수 구현해본 경험을 쌓으신 거예요.

 

 

마무리 🎯

지금까지 FastAPI와 SQLAlchemy를 활용한 실전 API 프로젝트를 함께 구현해보았습니다.

단순한 Hello World 수준을 넘어, 사용자 생성부터 게시글/할일 등록, 조회 API까지 완성된 상태의 백엔드가 완성되었죠.

직접 설계한 데이터 모델, 모듈화된 프로젝트 구조, 그리고 인터랙티브한 Swagger UI 테스트까지. 이건 단순한 튜토리얼이 아니라, 실무 감각을 기를 수 있는 제대로 된 훈련이었어요.

 

이번 실습이 끝이 아니라는 점, 기억해주세요!

이후에는 글 수정 및 삭제 기능, 댓글 기능, JWT 인증 및 권한 관리, 에러 핸들링 구조화, pytest를 활용한 테스트 자동화 등 보다 확장된 기능을 다룰 예정입니다.

 

실제로 서비스를 만들고 싶다면 지금 만든 코드를 바탕으로 Docker, GitHub Actions, AWS EC2 배포까지 이어가볼 수 있겠죠? 이제 여러분 손에 달렸습니다.

지금 당장 터미널을 열고 새로운 아이디어로 코딩을 시작해보세요.

세상에 단 하나뿐인 여러분만의 API 서비스가 될 수도 있으니까요!

반응형

+ Recent posts