화면 중앙에 캘린더 배치(다이어리 수첩 느낌 프론트 꾸미기) → 오늘 날짜에 하늘색으로 표시됨
캘린더에서 각 날짜 클릭하면 해당 날짜의 일기 화면으로 이동
일기가 작성된 날짜엔 녹색으로 표시 (오늘 날짜인데 글 작성하면 하늘색이 우선됨)
전체적인 테마는 하늘색, 녹색, 핑크색 등 파스텔 톤에 심플하면서 귀여운 테마
화면 상단 중앙에는 ‘(사용자 닉네임) Diary’으로 제목 로고 있음. 상단 우측에는 ‘로그아웃’버튼 있음(누르면 로그아웃하고 로그인 화면으로 이동)
3) 일기 화면 (메인 화면의 캘린더 날짜 누르면 나오는 화면)
게시판처럼 심플하게 목록 형태로 해당 날짜의 전체 글 목록 나타남. (최신 글이 상단에 오게끔 정렬, 각 글은 제목과 작성 시간만 나타나 있음.)
목록 상단 우측에는 ‘글쓰기’ 버튼 있음. → 누르면 글 작성 화면으로 이동
각 글 누르면 상세 조회 화면으로 이동.
4) 글 작성/수정 화면
제목과 내용 입력하는 칸 있음. (칸 구분은 그냥 선으로만 함. (핸드폰 메모 앱 같은 UI)
우측 상단에 ‘저장’버튼과 ‘취소’버튼 있음. (누르면 글 전체 조회 화면으로 이동)
5) 상세 조회 화면
제목, 내용, 작성 시간, 수정 시간 나옴.
우측 상단에 ‘수정’ 버튼 있음.
4. 데이터베이스 설계
1) 요구사항 분석
화면 설계 내용에 따라, 저장이 필요한 항목들만 추출하여 엔티티 속성으로 담는다.
diary 엔티티
제목
내용
작성 시간 (자동 저장)
수정 시간 (자동 저장)
user 엔티티
아이디
비밀번호
닉네임
☆처음 고민 : 캘린더의 날짜 별로 일기를 저장해야 하니까, 그러면 캘린더 엔티티도 만들어서 따로 저장하고 연관 관계를 구성해야 하나? -> diary 엔티티에 날짜 정보를 넣은 다음에, 이후에 캘린더 날짜를 클릭하면 해당 날짜 글만 조회해서 갖고 오는 형식으로 하면 될 듯
2) 연관 관계
한 명의 사용자가 여러 일기를 작성하므로 연관 관계는 다음과 같다.
user : diary = 1: N
이때 N쪽이 연관 관계의 주인(수정 가능)이기 때문에 외래키(FK)를 갖는다.
또한 @ManyToOne이므로 기본 즉시 로딩 패치 전략에서 Lazy 지연 로딩 설정으로 바꾼다. (추후 N+1 문제 대비)
(쿼리 파라미터 대신에, SecurityContext에 저장해두었으니 필요할 때마다 꺼내 쓸 수 있음)
6. API 설계 / 명세서
노션에서 아래 사진처럼 각 기능마다 request / response를 명세화했다. ㅎㅎ
1) 사용자 API
-회원가입 / 로그인
☆처음엔 Map으로 안 하고 그냥 String으로 문자열만 반환했었는데, 그렇게 하니까 프론트엔드에서 json으로 처리하려고 했는데 단순 문자열이라 파싱 오류나서 아래처럼 오류가 났었다.
그래서 Map을 이용해서 json처럼 반환하는 걸로 수정한 상태이다. (이에 대한 자세한 설명은 이후에~~)
2) 글 API
-월별 글 등록 날짜 조회 / 날짜별 글 전체 목록 조회
-글 상세 조회 / 글 작성
-글 수정 / 삭제
7. 프로젝트 세팅
먼저 Spring의 복잡한 환경 설정을 간단하게 자동으로 해 주는 Spring Boot를 사용하기 위해 아래 사이트에서 파일을 생성한다.
▣ 일단 우측 의존성 추가에 신경 쓰느라 지금 봤는데 좌측에 Configuration을 선택하는 게 있었다... 이후에 코드에서 Yml로 바꿨는데 미리 선택할 수 있는 것 같다.
그리고 최신 버전으로 4.0.3 기본으로 선택했는데, 나중에 AWS에서 EC2로 배포할 때 jackson 파일을 사용하는 과정에서 오류가 발생했다. 그게 스프링부트 버전이 높아서 내리면 괜찮다고 하는데, 이미 코드를 작성해 놓은 상태라 혹시 꼬일까 봐 우선 EC2에선 jackson 관련한 yml 설정을 지우는 걸로 했다... 그래도 다행히 프론트엔드에서 파싱 오류가 나진 않아서 괜찮았는데, 추후에 더 테스트 해 보고 방법을 결정해야겠다.
의존성을 추가한 다음에 파일을 생성하고, 인텔리제이에서 해당 프로젝트 폴더의 build.gradle 파일을 선택하면 프로젝트가 열린다. 여기에 JWT와 H2 관련한 의존성을 더 추가한다.
application-local.yml을 같이 실행하기 위해서는 여기에 profiles: active: local을 꼭 적어줘야 한다.
EC2에선 오류나는 jackson 라인을 다 없앴는데 그래도 파싱 오류는 나지 않았다. 아마 프론트에서 따로 코드를 추가했었는데 그 덕분에 괜찮은 것 같다. 아니면 springBoot에서 자동으로 해 줘서 괜찮거나 아직 테스트가 부족해서 오류를 못 잡은 거일 수도 있는데 이 부분은 더 공부를 해야겠다...
cmd에서 MySQL DB를 생성, 계정과 권한 설정한 걸 토대로 local yml에 그 정보를 적어준다.
jwt secret에는 토큰 (마음대로 설정, 256bit 이상)과 만료 시간을 적어준다.
cmd
mysql -u -root -p
(비밀번호 입력)
//DB 생성
CREATE DATABASE (DB 이름 입력);
//계정 생성 (예전에 다른 DB에서 쓴 계정이라도 이름과 host가 똑같으면 오류남. DB명대로 새로 만드는 게 나음)
CREATE USER '(user명)'@'localhost' IDENTIFIED BY '(비밀번호)';
//계정에 권한 부여
GRANT ALL PRIVILEGES ON (DB명).* TO '(user명)'@'localhost';
//저장
FLUSH PRIVILEGES;
application-local.yml
#절대 깃허브에 올리면 안 됨 -> gitignore에 파일명 추가
spring:
datasource:
url: jdbc:mariadb://localhost:3306/____
username: ____
password: ____
driver-class-name: org.mariadb.jdbc.Driver
jwt:
secret: "_____________________________________" #256bit 이상 필요
expiration: 86400000 #24시간 (ms 단위)
여기까지 하면 설정은 끝났고, 이제 코드 작성을 위해 패키지와 파일을 구성한다.
인텔리제이에서 아래와 같이 패키지 구조를 설계했다.
기본적으로 domain, controller, service, repository 계층으로 나눠지고
그 사이에서 데이터를 송수신할 dto,
인증/인가를 위한 security,
예외처리 통합을 위해 exception 패키지를 추가했다. (<-이거 안 하면 백엔드에서 예외처리 넘겨도 프론트엔드에서 단순히 500에러라고만 받아서 뭔 내용인지 자세히 모르기 때문에, 정확히 400 ~(메시지 오류 내용)등을 받을 수 있도록 코드를 추가했다.)
또한 이후에 추가한 test 파일들은 다음과 같다.
test 코드를 작성할 땐 본 파일 구조와 똑같이 해야 자동으로 그에 맞게 테스트를 돌려주니, 여기에서도 동일하게 패키지 구조를 따랐다.