/weather-diary-service

사용자가 게시글을 업로드한 시점의 날씨와 일기를 적을 수 있는 서비스

Primary LanguagePython

Weather Diary Service

사용자가 게시글을 업로드한 시점의 날씨일기를 적을 수 있는 서비스


목차


개발 기간

2022.09.06 ~ 2022.09.07 : 기능 구현

2022.09.12 : 버그 수정 및 테스트 코드 작성

프로젝트 개요

프로젝트 주체

띵스플로우

thingsflow


💭 프로젝트 설명

사용자가 게시글을 업로드한 시점의 날씨일기를 적을 수 있도록

아래의 개발 조건을 만족하는 REST API 서버 개발


🛠 개발 조건

  • 제목본문으로 이루어진 게시글은 이모지를 포함할 수 있고 각 20자, 200자로 제한됨

  • 회원가입, 로그인 없이 비밀번호만 일치하면 수정·삭제가 가능하며 비밀번호는 암호화 되어야 함

  • 비밀번호는 6자 이상이어야 하며 숫자 1개 이상 반드시 포함되어야 함

  • 모든 게시글은 최신글 순서로 확인 가능

  • 게시글은 20개 단위로 Pagination되어야 함

  • Weather API를 활용하여 게시글 등록시 날씨가 반영되어야 함


🧹 사용 기술

  • Back-End : Python, Django, Django REST framework
  • ETC : Git, Github, Azure

📰 모델링

무제 2


🛠 API Test

요구사항을 바탕으로 한 15개의 테스트 구현

1. 본문(content)
    1) 본문이 200자 초과할 때 : 실패
    2) 본문이 200자 초과하지 않을 때 : 성공
    3) 본문에 이모지 포함되어 있을 때 : 성공

2. 제목(title)
    1) 제목이 20자 초과할 때 : 실패
    2) 제목이 20자 초과하지 않을 때 : 성공
    3) 제목에 이모지 포함되어 있을 때 : 성공

3. diary create시
    1) 비밀번호가 6자 이하일 때 : 실패
    2) 비밀번호가 6자 이상일 때 : 성공
    3) 비밀번호가 문자로만 이루어져 있을 때 : 실패
    4) 비밀번호가 1개 이상의 숫자로 이루어져 있을 때 : 성공
    5) 비밀번호가 암호화 되어 있는지 확인

4. diary update시
    1) 비밀번호가 틀렸을 때 : 실패
    2) 비밀번호가 맞을 때 : 성공

5. diary delete시
    1) 비밀번호가 틀렸을 때 : 실패
    2) 비밀번호가 맞을 때 : 성공

프로젝트 분석

  • 일기를 중심으로 이에 대한 CRUD를 구현 (DRF의 Viewset 이용)
  • 비밀번호 암호화를 위해 직접 알고리즘을 구현할 수 있지만, 보안과 관련된 만큼 검증된 bcrypt 라이브러리 이용
    • 모델에서 Password 필드 정의Custom한 Validator를 통해 비밀번호 조건을 검증
    • 비밀번호 유효성 검증은 Serializer의 Create, Update method를 override하여 구현
  • 이모지를 포함하기 위해 DB마다 다른 접근법이 요구됨을 확인
    • Sqlite, PostgreSQL : 이모지 포함 가능 ( 이번 프로젝트의 경우Sqlite, PostgreSQL 를 이용하므로 설정 변경 없음)
    • MariaDB , MySQL : 4 byte로 이루어진 일반적인 UTF-8 과 달리 UTF-8인코딩시 각 char는 3 byte로 구성
      • 4 byte의 이모지를 저장하기 위해서는 UTF-8 인코딩 방식 이용 불가
      • UTF-8mb4 인코딩 방식을 이용해야 함
  • 게시글의 잦은 CRUD 작업이 발생될 것을 판단하여 데이터의 중복 또는 누락을 막기 위해 Cursor-base-Pagination를 이용
  • IP 주소를 바탕으로 사용자마다 현재 지역의 날씨 정보를 가져옴
    • XFF(X-Forwarded-For) HEADER 로부터 IP 주소 가져옴
      • IP Spoofing 등의 보안상 이슈가 있음을 확인하였으나, 민감한 개인정보를 다루지 않으므로 괜찮다고 판단
      • IP 주소를 얻지 못하는 경우 Seoul를 기준으로 함

API ENDPOINT

URL Method Action Description
"api/v1/diaries" GET List diary 전체 목록 조회
"api/v1/diaries" POST Create diary 생성
"api/v1/diaries/int:pk" GET Retrieve diary 세부내역 조회
"api/v1/diaries/int:pk" PUT Update diary 세부내역 업데이트
"api/v1/diaries/int:pk" PATCH Partial_Update diary 세부내역 업데이트
"api/v1/diaries/int:pk/" DELETE Delete diary 삭제 불가능
"api/v1/diaries/int:pk/delete" POST POST diary 삭제
  • Delete시 비밀번호 유효성 검증을 위해 viewsetDelete 대신 POST 방식의@action decorator이용

Troubleshooting

`암호화`에 대한 부족한 이해
  • 초반에 Django에서 제공하는 기본 암호화 함수가 아니라 Argon2라는 라이브러리를 이용하여 암호화를 진행
  • 최신 알고리즘인 만큼 문서가 부족하여 PasswordHasher() 함수에 대해 이해하는데 많은 시간을 소요함
  • Password를 str 형태로 비교해야한다는 점을 알지 못해 이로 인한 시간을 낭비함
  • 결국은 viewset의 문제점들로 대중적인 bcrypt를 이용하여 기능을 구현
  • 과제를 마무리하기 위해 시간을 효율적으로 관리해야 할 필요성에 대해 체감
`Serializer`에서 유효성 검증의 어려움
  • 유효성 검증을 SerializerView 중 어느 수준에서 진행해야 하는지에 대해 많은 시간 소요

    • View에서는 perform_create, perform_update, perform_destory 등 인스턴스를 DB에 처리하는 로직을 가지고 있을 뿐
    • DRF의 Source Code를 참고했을때 실질적인 데이터의 유효성 검증 및 생성은 Serilizer에서 진행된다고 판단
    • Serializer에서는 Create시, Update시에만 유효성 검증 가능
      • Delete Serializer를 따로 구현하여 Update method 로직을 바꿔 Delete method로 이용하려했으나 실패
      • 기간안에 Delete시 유효성 검증에 대한 적절한 방법을 찾지 못함
        • 후에 @action decorator를 이용하여 delete하도록 변경하여 기능 구현
  • 유효성 검증이라는 Serializer의 기능에 대한 이해 부족으로 판단되어 추후 학습 예정

`Viewset`의 단점
  • 반복되는 코드를 줄이고자 Viewset을 이용하여 CRUD를 구현하였으나, 각 method에 대한 정확한 이해가 부족
  • 특히 Viewset의 Destory method는 유효성을 검증하는 로직이 없음을 확인하는데 오랜 시간을 소요함
  • Viewset 대신 Apiview를 이용할 필요성에 대해 체감, API v2를 Apiview를 이용하여 추후 구현 예정

TIL