Git Product home page Git Product logo

ootw-backend's Introduction

outfit-of-the-weather

[#OOTW] 그날의 날씨를 보고 오늘의 코디를 공유하는 커뮤니티 By 빽엔두리

Untitled presentation (4)

프로젝트 주제

클론 타겟

  • 꾸온꾸
  • 현재 날씨를 확인하고 날씨에 맞춰 아바타를 코디한 후 전국의 여행지를 배경으로 사진을 찍어 업로드하는 게시판
  • 레퍼런스 이미지

image

개발 목표

  • 현재의 날씨를 보고 그에 맞는 아바타 코디를 선택해 이미지를 저장할 수 있고 저장한 이미지를 공유할 수 있는 게시판을 만드는 것을 1차 프로젝트 mvp로 삼고 진행
  • 이후 프로젝트 고도화에 따라 여러 기능을 추가적으로 구현 예정
  • 최종적으로 해당 콘텐츠를 메인으로 아바타 아이템 상거래가 가능한 커머스 시스템 도입을 목표로 진행 예정
moscow
  • Must Have: 날씨 API 기반 게시글, 사용자 인증, 이미지 서비스
  • Should Have: 댓글, 무한 스크롤, 사용자 인증/인가, 소셜 로그인, 좋아요, 해시태그, 히스토리
  • Could Have: 검색, 서비스 구독, 사용자 권한, 사용자 인증/인가
  • Won't Have: 게시글 북마크, 알림, 이메일, 아바타 아이템 커머스, 통합회원, 휴대폰 인증

기술 스택

  • java 17
  • springboot 3.2.0
  • spring security
  • jsonwebtoken jjwt 0.12.3
  • openfeign 4.1.0
  • spring data jpa
  • spring data redis
  • spring mail
  • green mail
  • minio 8.5.7

팀 역할(SM, PO, Dev)

SM PO Dev
이세희 이중원 김현우
  1. 그라운드 룰

    • 트러블 슈팅 경험은 2주 내에 기록하고 공유
    • 가독성을 중요하게 생각하여 코드 작성.
    • 서로의 지식을 공유하고 코드와 의견을 존중하자
  2. 스크럼 규칙

    진행 시간 내용
    매일 오전 9시, 15~30분
    (QR 찍고 진행)
    - 어제 한 일(전날 커밋 기록) 공유
    - 오늘 할 일(체크 리스트) 공유
    금요일 오전 9시
    (QR 찍자마자 진행)
    - 스프린트(1주) 회고, 피드백
  3. 트러블 슈팅

  4. 프로젝트 관리

주요 기능

유저 기능

  • 회원가입
    • Email 검증
      • RFC 5322 기준의 정규 표현식 검증
      • 최대 길이 255
    • Password 검증
      • 최소 한 개 이상의 영문자, 숫자, 특수문자가 각각 필요
      • 최소 길이 8, 최대 길이 30
      • DTO에서 @Password 커스텀 어노테이션 기반으로 진행
      • Entity 생성자를 통한 2차 검증
  • 인증 코드 발송
    • 회원가입 시 회원가입한 Email로 인증 코드 날리는 시스템 도입 (재전송 가능)
    • Spring MailSender로 회원 가입자 이메일로 회원 가입 인증 코드 전송
    • mail을 보내는 메서드는 @Async를 이용하여 비동기 처리
    • 회원 정보를 저장하되 회원 인증 여부(certified)를 false로 저장하고 true가 될 때까지 로그인 서비스를 이용할 수 없게 설정
    • GreenMail 라이브러리를 통한 인증 코드 전송 테스트 진행
  • 회원가입 코드 인증
    • 가입한 이메일과 코드를 body에 담아 회원 가입 인증 진행
    • 회원 테이블의 certified column을 true로 변경하고 로그인 하여 사용할 수 있게 만듬
    • 인증 코드를 Redis에서 관리
    • Redis TTL 설정으로 10분이 지난 인증 코드는 만료 처리
  • 로그인
    • jwtToken 기반의 인증 시스템 도입
    • 로그인 정보를 받은 후 유저 검증 후 TokenProvider를 통해 토큰 발급 및 검증
    • 토큰 프로세스는 jsonwebtoken jjwt 라이브러리를 활용
  • Token 인증 필터
    • SecurityFilter 내부에 JwtAuthenticationFilter를 추가
    • JwtAuthenticationFilter에서 로그인 시 사용한 토큰을 파싱 후 userId를 기반으로 UsernameAuthenticationToken을 생성 후 SecurityContext에 저장
    • 로그인이 필요한 API에서 Authentication 객체를 받거나 직접 principal을 호출하는 메서드로 user 정보 호출

현재 날씨 조회 기능

  • 기상청 OpenAPI 호출
    • OpenFeign을 이용하여 기상청 API를 호출
    • 기상청 API 응답 중 현재 날씨 정보(현재 기온, 강수 형태, 하늘 상태) 정보 조회
    • 복잡한 OpenAPI 응답을 처리하기 위해 @JsonDeserialize 를 이용하여 API 응답 비직렬화 구현
    • 요청이 제한된 기상청 API를 반복적으로 호출하는 문제 상황
      • 추후 날씨 요청 위치를 Enum(시.도.동 등)으로 관리하고 Redis 기능을 이용하여 캐싱 기능 추가하여 외부 API 중복 호출을 줄일 예정
  • Coordinate 클래스 유효성 검사
    • @Grid 커스텀 어노테이션 기반으로 Controller에서 유효성 검사 진행

게시판 기능

  • 게시판 CRUD 기능 작성
    • 로그인 여부에 따라 보여주는 정보 분기문 작성
    • jmeter 부하 테스트 중 게시글 목록 조회 성능이 가장 안 좋은 것을 확인
      • 추후 조회 성능을 더 분석해보고 개선 예정
      • 목록 조회는 필터 조회 기능을 추가할 예정
    • 게시글 생성 시 OpenFeign을 이용하여 기상청 OpenAPI 호출
      • 게시글 작성 시 일교차(최저/최고 기온) 정보 반영하여 저장
    • 레이어별 요청 값 유효성 검사
      • 요청 dto에서 annotation으로 1차 유효성 검사
      • Entity 생성시 2차 유효성 검사
  • 게시판 좋아요 기능
    • 좋아요 여부(isLike) 바꿔주는 Patch API로 좋아요 기능 처리
    • 게시글에 좋아요가 눌러진 숫자를 게시판 테이블에 추가
    • 좋아요 동시성 문제 해결
      • 한 사람이 한 게시물에 대해 여러 번 좋아요를 눌러서 생기는 문제
      • 여러 사람이 한 게시물에 대하여 동시에 좋아요를 누르는 문제
      • 비관적 락(Pessimistic Lock)을 사용하여 동시성 문제 해결
        • jmeter 부하 테스트 중 두 번째로 성능이 안 좋은 것을 확인 (평균 시간이 전체 조회를 제외하고 가장 오래 걸림)
        • 추후 성능 테스트 결과 확인 후 낙관적 락(Optimistic Lock) or Redis를 이용한 성능 개선 예정

아바타 이미지 기능

  • 아바타 이미지 등록 및 조회 기능
  • Enum Validation annotation 생성 및 적용
    • 모든 Enum 타입을 String으로 받고 그 Enum에 해당하는 값이 존재하지 않을 시 예외를 반환하는 annotation 생성
  • AvatarItem 전용 validation 클래스로 Entity validation 진행
  • 파일 저장 오픈 소스 MinIO 도입
    • 추후 배포 시 S3와의 호환성을 위해 로컬 작업에서 MinIO를 도입

      → S3 설정과 MinIO 설정 및 메서드가 동일하여 interface로 작성, 배포 버전에서는 S3 도입 예정

    • Docker를 이용해 컨테이너로 이미지 저장소 생성

    • MinIO 설정 후 이미지 저장 및 이미지 URL 반환 서비스 생성

    • 게시판, 아바타 이미지에 로직 진행 중 이미지 저장 후 실패하면 이미지 삭제하는 로직 추가

    • 대용량 이미지, 이미지 이외의 타입을 필터링 해주는 annotation 기반 validation 적용

    • Post, AvatarItem 등 이미지를 사용하는 테이블이 많아 이미지를 관리할 수 있는 별도의 테이블 생성

    • 추후 아바타 이미지/게시글의 수정 삭제 로직 후 발생 가능한 이미지 정합성 문제 확인 및 scheduling을 도입, 일정 시간 마다 @Async 를 이용하여 비동기적으로 처리 작업중

    • filename의 unique 조건을 위해 UUID를 이용한 filename 생성 도입

CI 도입(Github Action)

  • pull request 시 테스트 코드를 모두 돌려보는 CI 환경 생성
    • 로컬환경과 동일하게 Docker-compose 기반의 컨테이너 구동 후 test, build를 진행하는 방식 적용
  • github secret 기반으로 환경 변수 지정
  • Jacoco 테스트 리포트 자동화

Jacoco 도입

  • test coverage를 설정하여 기능 개발 시 test code를 작성하지 못한 케이스 확인
  • 메서드 개행 제한 및 분기문에 따른 test 기준 추가
    • Class Line Coverage → 70% 이상
    • Branch Coverage → 70% 이상
    • Method Line Count → 20줄
  • 전체 프로젝트 테스트 커버리지 ✨98.48%✨ (2024.01.18 15:00 기준)

Check style 도입

  • google checkstyle 파일을 기반으로 팀 프로젝트에 적합한 코드 스타일 컨벤션 정의
    • import 문, 여백 등 코드 스타일 컨벤션을 build 시 확인할 수 있도록 gradle 설정
  • 정의한 checkstyle 파일을 통해 Intelij 코드 스타일 자동 정렬 설정

JMeter 부하 테스트 실행

  • 수치로 나타난 객관적인 성능을 파악하기 위해 일부 API 부하 테스트 진행
  • 동시 접속이 많아지면 일부 요청이 예외를 반환하는 것을 확인
    • 최대 DB Connection Pool을 조절함으로써 해결

ootw-backend's People

Contributors

sehee-lee-01 avatar shoeone96 avatar asak1104 avatar

Stargazers

 avatar

ootw-backend's Issues

✅ Jacoco 도입하기

Issue: ✅ Jacoco 도입하기 #13

Description

프로젝트 개발 과정에서 자바 클래스에 대한 테스트 커버리지 확인 작업을 자동화할 필요가 있다.

Todo

  • Jacoco plugin 적용
  • Java 코드에 대한 커버리지를 체크

✅ CI 적용하기

Issue: ✅ CI 적용하기 #12

Description

  • pull request 적용 시 자동으로 테스트와 lint 적용등이 가능하게 CI pipeline을 구축 필요

Todo

  • CI 툴 선택(github action vs jenkins)
  • 선택에 따라 CI 설정
  • 설정 후 정상 작동하는지 확인 필요

ETC

  • 추후 해야할 일(참고)

CI 설정 이후 pull reque 시 정상적으로 작동하는지 테스트 필요

✅ 사용자 인증 요청 및 user entity validation

Description

Controller, Service, User enitty에서의 Email, Password, Nickname 필드 검증 기능이 필요

Todo

  • Email 검증 기능 추가
  • Password 검증 기능 추가
  • Nickname 검증 기능 추가
  • 회원가입 시 image 데이터가 필요 없도록 수정
  • GlobalControllerAdvice에서 필요한 Handler 추가

🔩 게시글 수정/삭제에서 게시글의 이미지 삭제 기능

Issue: 🔩 Refactoring

게시글 수정/삭제에서 게시글의 이미지 삭제 기능 구현

Description

게시글을 수정/삭제할 때 저장된 이미지를 버킷에서 삭제한다.

Todo

  • 게시글 이미지 수정 시 기존 이미지 삭제
  • 게시글 삭제 시 기존 이미지 삭제

ETC

  • Post 테이블 필드와 도메인 변경 필요

🔩 코드 스타일 통일

Description

코드 스타일 통일하기

Todo

  • checkstyle 스타일 확인
  • 다같이 의논한 것 반영

ETC

✅ API 서버 타임 존 설정

Description

서버 타임 존 설정이 컴퓨터 기본 설정이 아닌 아시아/서울로 설정이 필요

Todo

  • API 서버 타임 존 설정

🔩 게시글 목록 조회 페이지네이션

Issue: 🔩 게시글 목록 조회 페이지네이션

Description

게시글 목록 조회 페이지네이션이 필요하다.

Todo

  • 게시글 목록 조회 페이지네이션

ETC

기타사항

✅ 게시판 수정/삭제 기능 구현

Issue: ✅게시판 수정/삭제 기능 구현

Description

  • 게시글 수정/삭제 로직 구현
  • 구현 기능에 해당하는 테스트 코드 작성 및 수정

Todo

  • 게시글 수정/삭제 로직 구현
  • 구현 기능에 해당하는 테스트 코드 작성 및 수정

✅ Email 인증 코드 TTL 설정

Description

이전 PR (#62)에서 다루었던 사용자 이메일 인증 코드를 Redis에 저장할 때 TTL 설정이 필요

Todo

  • 사용자 인증 코드인 Certificate 객체에 대한 TTL 설정

ETC

기타사항

✅ checkstyle 적용하기(자바 Lint)

Issue: ✅ checkstyle 적용하기(자바 Lint) #11

Description

Code Style에 맞춰서 checkstyle 적용하기

Todo

  • 구글 google checkstyle 적용 후 커스텀
  • 기본 세팅
    • 클래스 앞 뒤 한 줄 설정
    • 한 줄 너비 120 설정
    • 와일드 카드 미포함 수정
    • 패키지 네임별 순서

ETC

  • 추후 해야할 일(참고)

  • 이슈 외에 추가로 한 일

    • 줄바꿈은 CRLF 대신 LF로 변경
      • 이유: 윈도우는 줄바꿈 문자가 CRLF(\r\n), 맥과 유닉스는 \n라서 추후 포맷팅했을 때 발생할 수 있는 문제 미리 정의. 또한 AWS 환경에서 운영하게 된다면 리눅스 환경이기 때문에 이 설정을 하는 것이 좋겠다고 생각!
  • html 리포트
  • 쿼리 DSL 스타일 확인
  • 메서드 라인 제한 확인만 해보기 => 기능이있다!

✅ 인증 서비스 구현

Issue: ✅ 인증 서비스 구현 #14

Description

OOTW 사용자의 인증, 인가 과정에서 사용할 기능이 필요
Spring Boot 애플리케이션 JWT를 라이브러리를 사용한 토큰 기반 인증 기능 구현

Todo

  • SecurityFilterChain 설정
  • 토큰 객체 생성 기능
  • Authentication 객체 생성 기능
  • 토큰 검증 기능
  • 토큰 기반 AuthenticationEntryPoint 추가
  • 토큰 기반 AccessDeniedHandler 추가
  • 토큰 기반 GenericFilterBean 추가
  • 토큰 기반 SecurityConfigurerAdapter 추가
  • 인증 API (#7 ) 개발

ETC

  • 추후 해야할 일

    • 토큰 기반 인증에서 로그아웃 기능을 구현하는 것은 쉽지 않다.
    • 추후 캐싱 서비스를 사용해서 블랙리스트 형식으로 우회적인 기능 개발이 필요

✅ #OOTW Server API Restdocs 명세서 추가

Description

OOTW Server의 API 명세서가 필요

Todo

  • Restdocs 설정
  • UserController 명세
  • CertificateController 명세
  • AvatarItemController 명세
  • PostController 명세
  • LikeController 명세
  • WeatherController 명세

✅ 이미지 관련 서비스 구현

Issue: ✅ 이미지 관련 서비스 구현 #16

Description

  • 이미지 저장 매체를 선정 후 spring project 내에서 이미지를 저장하고 불러올 수 있는 로직을 작성

Todo

  • 이미지 매체 선정(S3 vs Minio)
  • 선정된 매체에 이미지를 저장하는 로직 작성
  • 선정된 매체에 이미지 url 을 반환하는 로직 작성
    (아바타 이미지, 게시글 이미지의 url 저장을 위해)

ETC

  • 2023.12.20 오후 다같이 확인할 내용

Minio vs S3 선택

  • Minio: 오픈 소스로 전혀 비용이 들지 않는다, 다만 인프라를 직접 관리하기는 해야 할 것으로 보임, 추후 S3로 확장 가능
  • S3: 저장 이후 관리는 편하게 가능, 요금이 발생할 수 있으나 소액으로 감당 가능할 것으로 추정

추후 해야할 일(참고)

  • 이 기능 완성 후 커뮤니티 기능에서 정상적으로 이미지 업로드와 반환을 위해 디폴트 값들을 수정할 필요가 있음
  • 수정 후 테스트 과정도 필요

⚙️ 환경변수 설정

Issue: ⚙️ 환경변수 설정하기

Feature 요구 사항을 입력해주세요.

Description

  • 포트키, 비밀번호, 유저이름 환경변수 설정하기

Todo

  • yaml
  • docker 관련파일
  • 그 외

ETC

기타사항

🔩 인증 서비스 refactoring

Description

팀미팅에서 다뤘던 부분에 대한 보완

Todo

  • Validation 보완
    • email length
    • nickname length
  • 비밀번호 인증을 entity call 방식으로 변경

ETC

  • 추후 토큰 인증 모킹 편의를 위한 Annotation 도입 고려

커뮤니티 화면 스케치

커뮤니티 조회 예상 API
{
    "boardList": [
        {
            "userId": 1,
            "userProfile": "profileImg",
            "username":"username",
            "title": "title",
            "minTemperature": -1,
            "maxTemperature": 5,
            "likeCount": 50,
            "commentCount": 50,
            "hashtagList": [
                {
                    "hashtagId": 1,
                    "hashtagName": "대학생"
                },
                {
                    "hashtagId": 2,
                    "hashtagName": "혹한기"
                }
            ]
        },
        {
            "userId": 2,
            "userProfile": "profileImg2",
            "username":"username",
            "title": "title2",
            "minTemperature": -12,
            "maxTemperature": 0,
            "likeCount": 50,
            "commentCount": 50,
            "hashtagList": [
                {
                    "hashtagId": 1,
                    "hashtagName": "대학생"
                },
                {
                    "hashtagId": 2,
                    "hashtagName": "혹한기"
                }
            ]
        }
    ]
}

사용자 인증 API 명세서 작성

리뷰 요청 - @Sehee-Lee-01 @shoeone96

사용자 인증 API 명세서 1차 작성 완료했습니다
JWT를 사용하기 때문에 토큰 만료가 아닌 임의적인 로그아웃 기능을 위해선
블랙리스트 등록처럼 우회적인 접근 방식이 필요할 것 같습니다

명세서 작업 현황

  • 로그인 API
  • 회원가입 API
  • 로그아웃 API

로그인 API

[POST] /api/v1/auth/login

Request

  • Header
Key Value
Content-Type application/json
Accept application/json
  • Body
{
    "email": "[email protected]",
    "password": "user-password"
}

Response

  • status code
Code Message
200 Success to login
401 Unauthorized
  • Body
{
    "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
}

회원가입 API

[POST] /api/v1/auth/signup

Request

  • Header
Key Value
Content-Type application/json
Accept application/json
  • Body
{
    "nickname": "user-nickname",
    "email": "[email protected]",
    "password": "user-password"
}

Response

  • status code
Code Message
201 Success to signup
400 Bad request
  • Body
{
    "nickname": "user-nickname",
    "email": "[email protected]",
    "image": null,
    "createdAt": "2019-07-10T08:21:15.000Z",
    "updatedAt": "2019-07-10T08:21:15.000Z"
}

로그아웃 API

[POST] /api/v1/auth/logout

Request

  • Header
Key Value
Content-Type application/json
Accept application/json
Authorization Bearer {{jwt_token}}

Response

  • status code
Code Message
204 Success to logout
403 Forbidden

✅ 커뮤니티 기능 구현

Issue: ✅ 커뮤니티 기능 구현 #15

Description

  • 커뮤니티 게시글(Post)을 작성하고 조회할 수 있는 기능.
    • 게시글에는 기온/날씨 데이터가 담겨있다.
    • 사용자 권한 확인 없이 단순하게 게시글을 생성할 수 있다.
      • 이전 API 명세서에 있던 내용에서 사용자 인증/인가 관련 내용을 제외한 채 구현

Todo

Entitiy/JPA 설정

  • Post Entity에 기온/날시 관련 필드 추가
    • 최저 기온
    • 최고 기온
    • 현재 기온
    • 날씨: WeatherType라는 enum으로 우선 간략하게 표현
  • JPA ddl-auto: update 설정 후 슬랙 공유

API 구현

  • 예외처리 방식: Controller 내부에 ExceptionHandler 구현
    • 커스텀 예외 이전에 우선 기본 예외로 설정
  • 게시글 생성 api: POST /api/v1/post
  • 게시글 목록 조회 api: GET /api/v1/post
  • 게시글 상세 조회api: GET /api/v1/post/{postId}

테스트 코드/RestDocs 작성

  • Controller
  • Service
  • Entity
  • 그 외 RestDocs 등등

ETC

  • 2023.12.20 오후 다같이 확인할 내용

    • 명세서 수정 확인

      • 저번에 작성했던 (#8)과 함께 확인
        • 게시글 생성 API 요청에 userId를 넣기 vs requestparam 고려해보기
        • 게시글 생성 API 응답에서 Response Body에 user 관련 정보 제외하고 post 관련 정보만 반환
        • 게시글 목록/단건 조회 API에서 user_Id뿐만 아니라 user_Id, nickname, profile_image 담기(반정규화가 아닌 join으로 일단!)
        • 게시글 목록 조회 API에서 default로 created_at으로 최신순 정렬
      • 기온/날씨 데이터는 게시글 생성 요청시 Request Body에서 우선 default 값을 넣어준다.
      • 🚨 게시글 생성 api: 사용자 권한 확인 기능을 제외하고 단순 생성 구현
    • 기온 필드

      • 기온은 원시값보다는 Temperature 객체? vs 일단 빠르게 구현하도록 원시값 int
        • 유효성 검사를 할까 말까: 기존 이용하는 기상청 api가 제대로된 값을 줄 것이지만 확인차 해주는 것이 좋겠다는 생각! 프론트 단에서 어떻게 변경되어 올지 모른다.
        • 어디에서 할까: 현재 Must Have 자체에서는 여러 Entity 중 게시글에만 날씨가 들어간다. 하지만 Should Have 이상으로 갈 수록 날씨가 메인인 서비스가 많아질 것이기에 Post 자체에서 기온을 int로 받고 유효성 검사를 하는 것보다는 기온을 표현하는 wrapper 객체를 만들면 좋겠다는 생각!
    • 날씨 필드

      • 하늘상태(SKY) + 강수형태(PTY)
        • 기상청 api(단기예보)에서 우리가 쓸만한 정보 2가지가 있다.
          • 하늘상태(SKY) 코드 : 맑음(1), 구름많음(3), 흐림(4)
          • 강수형태(PTY) 코드: 없음(0), 비(1), 비/눈(2), 눈(3), 소나기(4)
    • DB/JPA

      • 우선 아까 이야기한대로 실행 환경은 ddl-auto: create로 가겠습니다!
  • 추후 해야할 일(참고)

    • 사용자 인증/인가 적용
      • 게시글 생성시 사용자 권한(익명X)/일치(다른 사용자X) 확인
      • 위 기능에 대한 예외처리
    • 구체적인 날씨 구현: 하늘상태 + 강수형태
    • 구조가 더 변경되면 예외처리 로직 개선(컨트롤러 어드바이스 추가하거나, 커스텀 예외 추가하거나,,,)

🔩 게시판에 최저/최고 기온 정보만 저장하도록 수정하기

🔩 게시판에 최저/최고 기온 정보만 저장하도록 수정하기

  • wetherService에 단기예보 요청 후 게시글 저장 당일의 최저/최고기온 불러오기 기능 구현
    • 게시글을 저장할 때 서버 내부적으로 당일의 최저/최고 기온을 불러오고 게시글 정보와 함께 저장한다.
    • 게시글을 조회할 때 게시글 작성 당일의 최저/최고 기온를 알 수 있다.
  • 테스트 코드 리팩토링 및 새로운 구조에 대한 테스트 코드 작성

커뮤니티 상세 화면 스케치

게시글 상세 보기 예상 API
{
    "boardsDetail": {
        "userId": 1,
        "userProfile": "profileImg",
        "username": "username",
        "title": "title",
        "contents": "contents",
        "minTemperature": -1,
        "maxTemperature": 5,
        "likeCount": 50,
        "commentCount": 50,
        "hashtagList": [
            {
                "hashtagId": 1,
                "hashtagName": "대학생"
            },
            {
                "hashtagId": 2,
                "hashtagName": "혹한기"
            }
        ]
    },
    "commentsList": [
        {
            "userId": 1,
            "userProfile": "profileImg",
            "username": "username",
            "comment": "comment",
            "likeCount": 50
        },
        {
            "userId": 2,
            "userProfile": "profileImg2",
            "username": "username2",
            "comment": "comment2",
            "likeCount": 50
        }
    ]
}

✅ 사용자 이메일 인증 기능 구현

Description

사용자가 사용하는 이메일에 대한 인증 기능이 필요

Todo

  • 이메일이 인증된 사용자를 구분할 수 있다
  • 이메일 인증은 최초 1회만 수행한다
  • 인증 코드를 생성할 수 있다
  • 생성된 인증 코드를 사용자 정보에 맞게 저장할 수 있다
  • 인증 코드를 사용자 메일 주소로 발송할 수 있다
  • 사용자 요청 시 인증 코드를 새로 생성하고 메일을 발송할 수 있다.
  • 이메일이 인증되지 않은 사용자는 로그인이 불가능하다
  • 이메일이 인증된 사용자는 로그인이 가능하다

ETC

  • 추후 TTL 설정을 통해 인증 코드가 만료되는 기능 추가 필요
  • 추후 이메일이 인증되지 않은 사용자에 대해선 권한을 낮게 설정해서 로그인이 가능하도록 수정

🔩 이미지 기능 Refactoring

Issue: 🔩 Refactoring

  • 사용하고 있지않는 이미지에 대한 관리 필요
  • 이미지 file 이름에 대한 관리 필요

Description

  • 사용하고 있지않는 이미지에 대한 관리 필요
    • 현재 수정, 삭제, 저장(저장 시 이미지만 저장되는 경우) 등 다양한 케이스에서 이미지가 삭제되거나 저장되고 있다.
    • 이 과정에서 이미지는 RDB에 직접 저장되는 정보가 아니다 보니 사용하지 않는 이미지가 버켓 안에 남이 있을 수 있다.
    • 사용하지 않는 이미지를 저장하고 있는 비용문제를 해결하기 위해 일정 주기로 확인해서 사용하지 않는 이미지에 대한 삭제가 필요하다.
    • 스케쥴링을 이용해 사용하고 있지 않는 이미지를 삭제할 필요가 있다.
  • file 이름 관리
    • 현재 로직에서는 파일에 사용된 이름 그대로 버킷에 저장하고 있는데 동일한 이름의 파일을 업로드 하는 경우 문제가 발생할 수 있다.
    • 파일 이름을 고유값으로 넣어 저장할 필요가 있다.
  • 이미지 directory 분리
    • 이미지 서비스 비중이 커지다 보니 한 directory에 분리할 필요성을 느꼈다.

Todo

  • 스케쥴링을 이용해 사용하고 있지 않는 이미지를 삭제 기능
  • file 이름 unique 값으로 관리
  • 이미지 directory 분리 및 테이블 생성

ETC

Spring project Entity 초기 세팅

Spring project Entity 초기 세팅

  • users, posts, avatar_appearance 테이블 DDL 스프링 프로젝트 내 추가
  • mysql DB container Dockerfile 이미지 생성
  • table에 매칭되는 ENTITY 클래스 생성

게시글 API 명세서 작성

코멘트

  • 에러 응답은 어떻게 하면 좋을지도 생각해보면 좋을 것 같습니다! 임의로 정해놓은 것이니,, 참고부탁드립니다!

게시글 API

  • 게시글 생성 API
  • 게시글 목록 API
  • 게시글 조회 API

게시글 생성 API

🚨 로그인한 사용자만 요청 가능

[POST] /api/v1/posts

Request

  • Header

    Key Value
    Content-Type application/json
    Accept application/json
    Authroization Bearer {{jwt_token}}
  • Body

    {
      "user_id": 1,
      "title": "일교차가 심할 때 좋은 코디",
      "content": "일교차가 심할 땐 목도리 필수! 가디건도 챙기면 좋아요!",
      "image": null,
      "weather": {
          "curr_temperature" : -10,
          "min_temperature" : -15,
          "max_temperature" : 0,
          "SKY": 4,
          "PTY": 3 
      }
    }

Response

  • status code

    Code Message Comment
    201 Success to create 성공
    400 Bad Request 잘못된 값으로 요청
    403 Forbidden 익명 사용자인 경우
  • Header & Body

    • Code: 201

    • 📷 image는 이미지 url이 들어온다.

      • Header

        Key Value
        Content-Type application/json
        Location {hostname}/api/v1/posts/1
      • Body

        {
          "id": 1,
          "title": "일교차가 심할 때 좋은 코디",
          "content": "일교차가 심할 땐 목도리 필수! 가디건도 챙기면 좋아요!",
          "image": null,
          "weather": {
              "curr_temperature" : -10,
              "min_temperature" : -15,
              "max_temperature" : 0,
              "SKY": 4,
              "PTY": 3 
          },
          "created_at": "2021-10-17T14:00:00.000Z",
          "updated_at": "2021-10-17T14:00:00.000Z"
        }
    • Code: 400

      • Header

        Key Value
        Content-Type application/json
      • Body

        {
          "errors": [
            {
              "field": "title",
              "message": "제목은 1글자 이상 30글자 이하로 입력해주세요."
            },
            {
              "field": "content",
              "message": "내용은 1글자 이상 300글자 이하로 입력해주세요."
            }
          ]
        }
    • Code: 403

      • Header

        Key Value
        Content-Type application/json
      • Body

        {
          "message": "게시글 생성 권한이 없습니다."
        }

게시글 목록 조회 API

[GET] /api/v1/posts

  • deafult: 최신순(created_at) 조회

Request

  • Header

    Key Value
    Content-Type application/json
    Accept application/json
  • Body

    {}

Response

  • status code

    Code Message
    200 Success
    400 Bad Request
  • Body

    • 📷 image는 이미지 url이 들어온다.

    • 우선 쿼리스트링 없이 최신순을 default로 조회

    • Code: 200

      {
        "posts": [
          {
            "id": 1,
            "user": {
              "user_id":1,
              "nickname":"이세희",
              "profile_image": null
            },          "title": "일교차가 심할 때 좋은 코디",
            "content": "일교차가 심할 땐 목도리 필수! 가디건도 챙기면 좋아요!",
            "image": null,
            "weather": {
                "curr_temperature" : -10,
                "min_temperature" : -15,
                "max_temperature" : 0,
                "SKY": 4,
                "PTY": 3 
            },
            "created_at": "2021-10-17T14:00:00.000Z",
            "updated_at": "2021-10-17T14:00:00.000Z"
          },
          {
            "id": 2,
            "user": {
              "user_id":1,
              "nickname":"이세희",
              "profile_image": null
            },
            "title": "OOTW 너무 좋은데요?",
            "content": "귀여운 캐릭터가 나왔어요!",
            "image": null,
            "weather": {
                "curr_temperature" : -10,
                "min_temperature" : -15,
                "max_temperature" : 0,
                "SKY": 4,
                "PTY": 3 
            },
            "created_at": "2021-10-17T14:00:00.000Z",
            "updated_at": "2021-10-17T14:00:00.000Z"
          }
        ]
      }
    • Code: 400

      {
        "errors": [
          {
            "field": "sort",
            "message": "sort는 latest만 가능합니다."
          }
        ]
      }

게시글 단건 조회 API

[GET] /api/v1/posts/{postId}

Request

  • Header

    Key Value
    Content-Type application/json
    Accept application/json
  • Body

    {}

Response

  • status code

    Code Message
    200 Success
    404 Not Found
  • Body

    • 📷 image는 이미지 url이 들어온다.

    • code: 200

      {
          "post_detail": {
              "id": 1,
              "user": {
                  "user_id": 1,
                  "nickname": "이세희",
                  "profile_image": null
              },
              "title": "일교차가 심할 때 좋은 코디",
              "content": "일교차가 심할 땐 목도리 필수! 가디건도 챙기면 좋아요!",
              "image": null,
              "weather": {
                  "curr_temperature": -10,
                  "min_temperature": -15,
                  "max_temperature": 0,
                  "SKY": 4,
                  "PTY": 3
              },
              "created_at": "2021-10-17T14:00:00.000Z",
              "updated_at": "2021-10-17T14:00:00.000Z"
          }
      }
    • code: 404

      {}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.