FastAPI 기본 게시판 CRUD API 실습
오랜만에 기본 게시판 CRUD API 실습 블로깅을 해본다.
이번에는 Python으로 진행한다.
업무로 FastAPI를 접하고 생각보다 너무 재밌어 다음에는 Django를 공부하고 싶어졌다.
각설하고 시작해보자
▶ FastAPI에 관련된 내용은 이전 블로깅 참고
https://datamoney.tistory.com/344
1. 프로젝트 셋팅
개발환경으로는 mac os
툴은 vscode를 사용했다.
일단 가상 환경을 만들어 진입해준다.
(개발 환경 구성부터 필요하다면 이전 블로깅을 참고...)
# 가상 환경 설정
pyenv virtualenv 3.10.6 [가상환경 이름]
# 가상 환경 실행
pyenv activate [가상환경 이름]
# poetry 설치
curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | python
# 기본 pyproject.toml 생성
poetry init
# 패키지 설치 (fastapi, uvicorn)
poetry add fastapi uvicorn
생성된 프로젝트를 열어본다.
프로젝트가 실행되고 첫 진입점을 만들어준다.
main.py
서버를 실행해준다.
uvicorn main:app --reload
http://127.0.0.1:8000 로 들어가보니 "hello world!" 가 출력되는 걸 볼 수 있다.
이렇게 프로젝트 셋팅이 끝났다.
2. DB 셋팅
간단한 실습이니 SQLite로 진행하겠다.
SQLite는 H2와 같은 경량 DB로 Python 내부에 기본 내장되어 있어 따로 설치할 필요가 없다.
ORM으로는 제일 대표적인 SQLAlchemy을 사용한다.
설치부터 해준다.
poetry add sqlalchemy
database.py
db설정 파일을 만들어 줬다.
SQLite는 기본적으로 한 번에 하나의 스레드만 DB에 접근할 수 있도록 제한되어 있기 때문에
DB 커넥션 풀을 생성할 때 connect_args={"check_same_thread": False} 를 줘서 여러 스레드에서 접근할 수 있도록 해준다.
연결된 DB를 실제로 확인해보려면 해당 DB에 연결해 명령어를 날려주면 된다.
sqlite3 fastapi.db
.databases
h2처럼 브라우저에서 직접 눈으로 확인하고 싶다면
DB Browser for SQLite 를 다운 받아 사용하면 된다.
3. 도메인 생성
기본 게시판이니
- no
- writer
- content
- date
컬럼을 가진 Board 테이블이 필요하다.
일단 도메인을 작성해준다.
models.py
+ 자동 테이블 생성 설정
JPA의 ddl-auto처럼 자동으로 테이블을 생성해주는 설정을 할 수 있다. 해당 설정은 모델과 DB를 연결하는 main에서 해준다.
하지만 이 설정으로는 테이블 변경 관리는 안되기에 변경 관리까지 원한다면 alembic을 설치해 진행하면 된다.
서버 재 실행 후 테이블이 잘 생성 됐는지 확인한다.
# 생성된 테이블 리스트 출력
.tables
# 생성된 테이블 컬럼 정보 출력
SELECT sql FROM sqlite_master WHERE tbl_name='테이블명';
+ 테이블 생성이 잘 됐는지, sqlite가 잘 실행되는지 확인해보기 위해 샘플을 넣어봤다.
4. 라우터 설정
controller 역할인 들어오는 요청을 받아 메서드를 실행시켜주는 라우터를 만들어준다.
board_router.py
해당 board_router를 등록해줘야하니 main.py도 열어 코드를 추가해준다.
서버를 재시작하고 docs를 확인해보면 이렇게 해당 get 메서드가 생긴걸 볼 수있다.
tag를 달아주면 default가 아니라 board로 나눠줄 수 있다.
5. CRUD API 구현
이제 진짜 기능을 구현해본다.
[C기능]
일단 게시판에 새로운 글을 create를 하기 위해서는
writer, title, content 를 담아 넘겨줘야 한다.
해당 데이터를 받아줄 dto부터 만들어준다. fastapi에서는 이를 스키마라고 한다.
일단 BaseModel을 생성해주기 위해선 pydantic이 필요하다. 데이터 모델의 기본 템플릿을 정의해주는 역할을 한다.
poetry add pydantic
board_schema.py
작성자와 제목은 필수로 지정하고 내용은 없어도 되게 만들었다.
이제 게시판을 생성하는 메서드를 만들어준다.
board_router.py
그리고 바로 db에 접근해 해당 게시글을 insert 해도 되지만 비즈니스 로직은 따로 구현하도록 한다.
board_crud.py라는 파일을 만들어 db와 통신하는 로직을 적어줬다.
board_crud.py
이제 이대로 실행해보자
Board에 담아줄 데이터를 받아 넣어주고
db에 추가, commit까지 해준다.
그리고 그 autoincrement로 생성된 no를 리턴 받아왔다.
실행
/board/create 경로며 request body에 필요한 값을 받아줬다.
실행해보니 응답에 no가 왔다.
SQLite을 확인해본다.
date와 del_yn은 default 값으로 잘 들어가진 것도 볼 수 있다.
[R기능]
- all
모든 게시글을 조회해보는 메서드를 만든다.
모든 게시글이지만 삭제된 게시글은 가져오면 안되니 del_yn이 'Y'인 것만 가져와야한다.
no가 2인 글의 del_yn을 N로 미리 조작했다.
board_router.py
/board/read 경로로 요청 받아 board_crud의 list_all_post 메서드로 보내준다.
board_crud.py
아주 간단하다.
Board의 모든 데이터를 가져오는데
여기서 del_yn라는 필터를 넣어 삭제된 게시글을 제외하고서 가져와줬다.
실행
del_yn가 'N' 인 2를 뺀 리스트가 잘 리턴 됐다.
데이터를 그대로 리턴해줘도 되지만
no, writer, title, date 이것만 리턴해주고 싶으니 따로 스키마를 만들어준다.
board_schema.py
다시 db에서 조회한 게시글 리스트를 이 스키마에 담아 리턴해준다.
board_crud.py
실행
이렇게 원하는 값들만 리턴해줄 수 있다.
- one
특정 게시글을 상세 조회하고 싶다. 특정 게시글의 no를 받아 조회해주기로 한다.
board_router.py
형식은 모든 리스트를 불러올때와 비슷하다
하지만 특정 no를 받아주기 위해 post_no를 path 파라미터로 받아주기로 한다.
받은 post_no를 board_crud의 get_post로 넘겨줬다.
board_crud.py
여기에는 filter 조건을 no가 넘어온 post_no와 같은가?를 추가해줬다.
filter 조건을 추가해주기 위해 그냥 , 로 써도 되지만 and_를 import 받아 써줘도 된다.
이 역시 스키마에 담아 리턴해주기로 한다.
board_schema.py
게시글의 content는 추가할때 썼던 NewPost 처럼 있을 수도 있고 없을 수도 있으니 Optional로 처리한다.
실행
no가 3인 게시글이 잘 조회된다.
만약 여기서 del_yn 이 'N'인 값인 no 2 게시글을 조회한다고 하면
AttributeError: 'NoneType' object has no attribute 'no'
이런 에러가 발생할 것이다.
이건 조건에 맞는 post 값이 없어서 나는 에러이며 예외 처리를 이런식으로 간단히 추가해줄 수도 있다.
물론 이 경우에는 response_model를 수정해줘야한다.
[U기능]
이제 게시글을 업데이트 해보자.
위처럼 특정 게시글을 조회해 데이터를 수정해 넘기면 그대로 반영하기로 한다.
게시글 수정은 제목과 내용만 가능하게 한다.
일단 스키마를 만들어준다.
board_schema.py
여기서도 content는 없을 수도 있으니 Optional로 처리한다.
board_router.py
일단 업데이트를 하기 위해선
no로 넘어오는 게시글이 있는지부터 확인해야한다.
만약 해당 게시글이 없다면 없다는 예외를 처리해줘야한다.
board_crud.py
실행
먼저 존재하지 않는 게시글 번호 2를 넘겨줬다.
해당 번호는 삭제된 걸로 되어있으니 예외가 발생돼 응답된다.
다시 유효한 게시글번호 3과 바꿀 제목과 내용을 담아 요청했다.
응답을 보아하니 수정이 잘 된것 같다.
sqlite로도 확인해봤다.
역시나 잘 됐다.
[D기능]
- del_yn 변경
현업에서는 일반적으로 실제 삭제하지 않고 del_yn 컬럼을 변경하기에 이번에는 patch로 해당 컬럼의 값을 수정해보겠다.
board_router.py
특정 게시글 조회와 같게 path 파라미터로 post_no를 받아준다.
board_crud.py
그리고 삭제 완료시 삭제가 완료됐다는 메세지를 응답해주기로 했다.
실행
이렇게 실행해보면
del_yn이 수정된걸 볼 수 있다.
sqlite 로 확인해보면 del_yn이 'N'으로 변경된게 확인된다.
전체 게시글 조회를 해보면
해당 게시글이 보이지않는다.
- 진짜 데이터 삭제
하지만 진짜로 해당 데이터를 삭제하고 싶다면?!
board_router.py
기본 포맷은 같다.
board_crud.py
대신 db.delete(post)
를 통해 실제로 값을 삭제할 수 있다.
중요한 건 commit()까지 해야 반영이 제대로 된다.
실행
정말 db에 해당 게시글이 삭제된걸 확인한다.
모든 게시글 list를 조회했다.
no 1이 사라졌다.
sqlite로도 확인해봤는데 없다.
잘 삭제가 된 것을 볼 수 있다.
이렇게 fastapi로 기본 crud 게시판 api를 만들어봤다.
굉장히 쉽고 빠르게 만들 수 있다.
코드
https://github.com/recordbuffer/TIL/tree/main/FastAPI
참고
https://wikidocs.net/175066
'Python > FastAPI' 카테고리의 다른 글
[FastAPI] OAuth2.0 소셜 로그인 회원가입 구현 SPA (구글 로그인 / 네이버 로그인 / 카카오 로그인) (1) | 2024.09.17 |
---|---|
[FastAPI ③] JWT 로그인 구현 실습 (Rest API / Bearer with JWT tokens / 쿠키에 토큰 저장) (2) | 2023.09.13 |
[FastAPI ②] 일반 회원가입, 로그인 구현 실습 (Rest API / 회원 가입 유효성 검증) (0) | 2023.08.17 |
[FastAPI] 파이썬 경량 프레임워크 (기본 개념 / 입문 / 개발 환경 구성) (0) | 2023.06.06 |
댓글