본문 바로가기
Backend/Python

[FastAPI] Project Levup - 메모 수정 & 삭제 기능 만들기

by 천우산__ 2023. 11. 29.

https://chunws13.tistory.com/52

 

[React] Project Levup - Axios 활용하기

백엔드에서 구현한 사항 : 메모 만들기, 메모 조회하기 백엔드에서는 로그인이 완료되면 토큰을 발급하고, 토큰과 함께 메모 조회 요청을 하면 해당 ID로 작성한 메모를 가져오도록 구현했다. 먼

chunws13.tistory.com

프론트엔드에서 메모 읽기와 쓰기 기능을 받아서 구현을 완료했으므로, 메모 수정 기능을 가진 api를 설계해 본다.

클라이언트에서 메모 id와 내용을 전달해 주면 memo db에서 id를 조회하여 저장된 내용을 바꾸면 될 것이다.

구현을 위해 클라이언트 측으로부터 받아야 하는 정보는 [ 메모 id, 수정할 내용, 로그인 토큰] 으로 총 3가지이다.

수정할 내용은 메모 생성 기능과 같은 모델을 사용하면 된다.

로그인 토큰을 검사하는 기능을 이후에 글을 쓰고 이 곳에 링크를 둘 예정

마지막으로 메모의 id를 받아야 한다.

 

1. 클라이언트로부터 정보 받기

@router.put("/{memo_id}")
def edit_memo(memo_id: str, Memo: Memo, Authorization : Annotated[Union[str, None], Header()] = None):
    checker = User_Auth(Authorization) # 로그인 토큰 정보로 객체 생성
    result = checker.check_auth() # 토근 유효성 검사

요청 받는 메모 id에 맞춰 작업하기 위해 요청 경로를 /{memo_id} 로 하였고, 이 값은 요청 받는 id에 따라 변하게 된다.

그 다음, edit_memo( ~ )에 해당하는 코드는 입력되는 변수들을 검사하는 과정이다.

memo_id 는 문자열과 숫자가 섞인 값으로 들어올 예정이므로 문자열로 받도록 했고

변경될 컨텐츠의 내용은 생성과 같은 모델인 Memo 모델과 같은지 검사한다.

마지막으로 클라이언트 요청의 Header 부분의 Authorization 의 값을 가져온다. ( Authoriztion 값은 변경 가능 )

Annotated : 이 부분이 궁금할 수도 있는데 

Union[str, None] 로 Auth의 값은 문자열 혹은 None 값을 가진다는 것을 의미하고

[Union[str, None], Header()] 부분은 요청 헤더에서 이 정보를 가져온다는 의미이다.

마지막으로 = None 은 기본값은  None 인 상태인 것을 의미한다.

 

요청 정보에 문제가 없으며, 로그인 토큰에도 문제가 없다는 것이 확인되면 id 기준으로 메모를 찾아야하는데, 주의할 점이 있다.

mongoDB의 id 값은 objectId라는 값으로 감싸져 있어서, 전달 받은 그대로 조회를 요청하면 id 값은 맞아도 조회가 되지 않는다.

이와 같은 문제를 해결하기 위해서는 obejctId 를 import 하여 감싸준 후 조회를 시도하면 정상적으로 조회가 가능하다.

 

전반적인 프로세스는

1. id를 기준으로 메모를 찾는다.
 - db에 해당 id가 없으면 -> 메모가 없다는 메세지 전달
 - id가 있으면 -> 다음 과정 시작

2. 요청 받은 id의 값(원래 메모)을 입력받은 수정 메모로 변경한다.
 - 이 때, 에러가 발생하면 -> 수정 실패 메세지 전달
 - 에러가 발생하지 않으면 -> 수정 성공 메세지 전달

 

2.  수정하기 API 구현 코드

from models.memo import Memo
from bson.objectid import ObjectId
from pymongo import MongoClient

@router.put("/{memo_id}")
def edit_memo(memo_id: str, Memo: Memo, Authorization : Annotated[Union[str, None], Header()] = None):
    checker = User_Auth(Authorization)
    result = checker.check_auth()
    
    if result["status"] == "success":
        target_id = ObjectId(memo_id)
        if db.memo.find_one({"_id": target_id}) == None:
            return {"status": "fail", "data" : "메모가 없습니다."}
        
        try:
            db.memo.update_one({"_id" : target_id}, {"$set" : { "content" : Memo.content }})
            return {"status" : "success", "data" : "수정되었습니다."}
        
        except:
            return {"status" : "fail", "data" : "수정 실패했습니다."}
    
    else:
        return result["data"]

 

3. 삭제하기 API

삭제하는 방법은 수정하는 방법과 큰 차이가 없다. 전반적인 프로세스는 수정하기와 같으나, 한 가지 차이점이 있다.

수정할 메모를 받지 않아도 된다. 그러므로 Memo 객체 검사를 할 필요가 없다.

이력 관리가 중요한 실제 서비스의 경우에는, 실제로 삭제하지는 않고 삭제된 상태로 변경하고 Get 요청시 조회되지 않도록 하지만

개인적으로 만드는 메모 앱 같은 경우에는, 그런 방법을 따를 만한 필요성이 없으며 무엇보다 삭제하지 않는 경우에는 데이터가 지속적으로 쌓여

DB 무료 사용량을 언젠가는 벗어날 수도 있기 때문에 DB 내에서도 삭제했다.