번개 지향 볼링 모집 커뮤니티 "번개볼링"의 백엔드 서버입니다.
카카오 테크 캠퍼스 1기 부산대 3조 프로젝트입니다.
기존의 볼링 관련 서비스들에서는 볼링 한판을 치기 위해서 동호회, 소모임에 가입을 해야하는 번거로운 과정이 필요합니다. 소모임, 밴드 앱 또한 일회성의 가벼운 만남이 아닌 주기적으로 참여를 할 회원을 모집하는 경우가 많습니다.
저희 번개 볼링은 기존과 차별화된 번개모임, 즉, 빠른 매칭을 목표로 하고 있습니다.
카테캠 수료 이후, 카카오 크램폴린이 더이상 지원 되지 않습니다.
현시점에서는 구성도와 다르게 단순히 AWS EC2 상에서 직접 구동 중입니다.
프로젝트를 클론합니다.
$ git clone https://github.com/Step3-kakao-tech-campus/Team3_BE.git
Temp3_BE/.env.example
파일을 .env
로 복사하고 내용을 자신의 환경에 맞게 설정해줍니다.
$ cd Team3_BE # 디렉토리 이동
$ cp .env.example .env # 파일 복사
$ vi .env # .env 수정
파일 수정 및 저장 진행하기
.env
파일은 환경변수를 설정하는 파일입니다.
TOKEN_SECRET="example" # 로그인시 사용되는 토큰의 시크릿 키를 설정
DOMAIN="http://localhost:3000" # 배포될 도메인을 설정
API_SERVER_URL="http://localhost:8080" # 서버URL 설정
GMAIL_USERNAME="example@gmail.com" # 메일인증 등 메일발신에 사용될 GMAIL설정
GMAIL_APPLICATION_PASSWORD="example" # 메일인증 등 메일발신에 사용될 GMAIL설정
AWS_ACCESS_KEY="example" # AWS S3에 접근하기 위한 키 설정
AWS_SECRET_KEY="example+9Vkr3fRwA" # AWS S3에 접근하기 위한 키 설정
MYSQL_USERNAME="example" # 데이터 베이스 연결 설정
MYSQL_PASSWORD="example" # 데이터 베이스 연결 설정
GOOGLE_MAP_API_KEY="example" # 구글맵 API 키 설정
SSL_KEY_PASSWORD="example" # SSL 키 설정
FLASK_MAIL_SERVER="http://localhost:5000" # 구동 시킨 Flask SMTP 서버의 주소
local profile을 사용할 시, SSL
과 MySQL
, Flask
설정이 불필요합니다.
.env
환경변수를 등록합니다. (본 가이드에선 우분투 환경으로 진행합니다.)
$ set -a
$ source .env
$ set +a
.mysql_env.example
을 복사하여 .mysql_env
로 복사하고 내용을 자신의 환경에 맞게 설정해줍니다.
$ cp .mysql_env.example .mysql_env # 파일 복사
$ vi .mysql_env # .mysql_env 수정
docker-compose.yml
파일을 이용해 Redis
및 MySQL
도커 컨테이너를 실행합니다.(도커가 설치되어 있다고 가정합니다.)
$ docker-compose up -d
java파일을 빌드, 실행합니다.
$ ./gradlew clean build
$ java -jar build/libs/server-0.0.1.jar
실제 배포를 위한 product
환경일 시, spring.profiles.active
설정을 추가하여 실행합니다.
$ ./gradlew clean build
$ java -jar -Dspring.profiles.active=product build/libs/server-0.0.1.jar
spring boot의 deploy profile을 사용하는 경우만 Flask SMTP 서버 실행이 필요합니다.
카카오 크램폴린 상의 배포에서 SMTP가 지원되지 않습니다. 따라서 별개의 네이버 클라우드 상에서 SMTP 서버를 구축하였습니다.
그 외의 profile은 spring boot 내에서 자체적으로 SMTP를 사용하여 메일을 전송합니다.
프로젝트를 클론합니다.
$ git clone https://github.com/Step3-kakao-tech-campus/Team3_BE.git
폴더를 이동합니다.
$ cd Team3_BE/flask
Flask SMTP 서버를 실행합니다.
$ ./start.sh
배포된 주소를 .env의 FLASK_MAIL_SERVER에 넣습니다.
개발한 API들의 핵심 특성을 서술합니다.
각 api들의 상세한 명세는 Swagger 문서를 확인 부탁드립니다.
JWT를 이용하였습니다.
회원가입을 하지 않은 유저는 아래의 기능만 사용이 가능합니다.(주로 조회만 가능)
- 행정구역 관련 기능
- 모집글 조회
- 댓글 조회
- 사용자 조회 (유저 기록 조회, 참여 기록 조회, 점수 조회)
회원가입을 한 유저는 아래의 기능을 추가로 사용할 수 있습니다.
- 자신의 회원정보 조회 및 수정
- 쪽지 조회
회원 가입 후 이메일인증을 받은 유저는 아래의 기능을 포함하여 모든 기능을 사용할 수 있습니다.
- 모집글 관련 모든 기능
- 신청 관련 모든 기능
- 댓글 관련 모든 기능
- 쪽지 관련 모든 기능
- 별점 등록, 점수 등록 기능
현재 SMTP 서버는 분리되어, Naver Cloud 상에서 배포 중입니다.
크램폴린 환경에서는 카카오 정책으로 인해 HTTP 통신만 가능하다는 프로토콜 통신 제한이 있어, 외부에 SMTP 서버를 구축하여 SMTP 이메일 전송을 구현하기로 하였습니다. POST 요청에 의한 이메일 발송만 구현하면 되었기에 간결하면서도 필요한 기능을 구현할 수 있는 도구를 선택하려고 하였고, 이에 간결하게 사용할 수 있는 웹 Framework인 Flask로 메일 전송 요청에 따른 메일 전송 기능을 구현하게 되었습니다.
크램폴린 환경에서만 Naver Cloud 환경에서의 flask 서버를 활용합니다.
HTTP POST 요청 생성하기
SMTP 요청 생성하기
정부의 행정구역 데이터를 db에 미리 작성해두어 행정구역 데이터를 직접 관리하도록 구현하였습니다.
행정표준코드관리 시스템 - 법정동코드 목록 조회 데이터 파일을 이용하여 sql 데이터를 생성하였습니다.
볼링 번개 모임을 모집하려는 사람이 작성하는 포스팅입니다.
모집글 데이터가 필요한 API를 구현하는 도중, 복잡한 조건처리가 필요한 로직이 있어 동적 쿼리가 필요했습니다. queryDSL
을 학습하여 도입하기에는 프로젝트 기간이 한정적이라 비교적 사용이 쉬운 JPA Specification을 사용하였습니다.
참여기록 데이터에 적용된 JPA Specification
의 일부 로직입니다.
private List<Post> loadPosts(CursorRequest cursorRequest, Long userId, String condition, String status, Long cityId, String start, String end) {
int size = cursorRequest.hasSize() ? cursorRequest.size() : DEFAULT_SIZE;
Pageable pageable = PageRequest.of(0, size, Sort.by(Sort.Order.desc("id")));
Specification<Post> spec = Specification.where(conditionEqual(condition, userId))
.and(statusEqual(status))
.and(cityIdEqual(cityId))
.and(createdAtBetween(start, end));
if (cursorRequest.hasKey()) {
spec = spec.and(postIdLessThan(cursorRequest.key()));
}
return postRepository.findAll(spec, pageable).getContent();
}
해당 부분에서 동적쿼리를 사용하지 않으면 30개가 넘는 조건을 처리해야 했기 때문에
JPA Specification
을 도입하게 되었습니다.
댓글에 대댓글을 달 수 있도록 설계하였습니다.
조회는 비회원도 가능하지만 작성은 회원만 가능합니다.
커서 기반 페이징을 하였습니다.
삭제된 댓글에 대댓글이 있는 경우 대댓글 표시를 위해 전달이 됩니다.
content: "삭제된 댓글입니다"
userId: null
그외, 대댓글이 없는 삭제된 댓글과 대댓글이 삭제된 경우의 댓글은 responseBody에 포함되지 않습니다.
삭제된 댓글들로 인한 통일되지 않은 응답 개수 문제가 존재합니다.
이는 프론트의 구현이 무한 스크롤로 이루어 지기 때문에 적은 개수가 응답되어도 자동으로 다음 key로 요청이 일어나 사용자 경험에 큰 영향을 주지 않을 것으로 판단되어 이렇게 구현하였습니다.
모집글 작성자 이외의 유저들은 모집글에 참여 신청을 할 수 있습니다.
모임 이후, 해당 모임에 대해 점수를 등록할 수 있습니다.
외부 저장소 - AWS S3
를 사용하였습니다.
닉네임, 이메일, 지역 정보, 매너 점수, 볼링 Avergae 점수 등을 사용자 정보로 관리합니다.
다른 사용자와 1대1 대화를 할 수 있습니다.