Plrecipe
는 "놀다"를 의미하는 Play
와 "요리법"을 의미하는 Recipe
의 합성어로, 사용자에게 다양한 놀거리를 제공하는 서비스입니다. 사용자는 음식점, 카페, 산책, 액티비티 등을 조합하여 자신만의 코스를 만들 수 있으며, 이를 기반으로 게시글을 작성하여 다른 회원들과 공유할 수 있습니다. 또한 사용자는 그룹을 생성하여 혼자 또는 친구들과 함께 게시물을 공유하고 추억을 쌓을 수 있습니다.
저희 프로젝트는 '플레시피'라는 이름으로, JAVA Spring, MyBatis, JPA, 외부 API를 활용하여 백엔드를 구현하고, 프론트엔드까지 구현하는 것을 목표로 하고 있습니다. 이 프로젝트는 구체적이고 기능의 고도화보다는 학습한 내용을 기반으로 주요 기능 중 구현 가능한 기능을 우선적으로 구현하여 진행되었습니다.
'플레시피'
서비스는 사용자가 원하는 장소를 조합하여 자신만의 코스를 만들고, 이를 게시글 형식으로 다른 사용자들과 공유할 수 있는 기능을 제공합니다. 또한, 사용자들은 회원끼리 모인 그룹 또는 혼자만의 그룹을 생성하여 추억을 저장할 수 있습니다.
이를 통해 사용자들은 자신의 여행이나 취향에 맞는 장소들을 조합하여 특별한 코스를 만들고, 이를 다른 사용자들과 공유하거나 추억을 남기는 등의 활동을 즐길 수 있습니다. 해당 프로젝트는 기능의 확장성을 고려하여 프론트엔드까지 구현하여 사용자들이 보다 편리하게 서비스를 이용할 수 있도록 할 것입니다.
위의 자료는 2021년까지의 여행자 비율과 레저시설 이용률에 대한 통계를 보여주고 있습니다. 그래프를 통해 하락하는 모습을 확인할 수 있는데, 이는 COVID-19의 영향으로 인한 것입니다. 이로 인해 자유로운 여행이나 활동이 제한되었고, 이는 여행자 비율과 레저시설 이용률에 영향을 주었습니다.
하지만 현재 COVID-19이 종식되면서, 사람들은 그 동안 하지 못한 여행이나 레저 활동을 즐기려는 움직임이 나타나고 있습니다. 종식된 지 약 1년이 지난 지금, 많은 사람들이 친구들과의 추억을 쌓거나 스트레스를 해소하고자 하는 욕구가 커지고 있습니다.
이러한 경향은 향후 여행 업계 및 레저 산업에 긍정적인 영향을 미칠 것으로 예상됩니다. 종식된 COVID-19으로 인한 제약이 풀리면서 사람들의 여행과 레저 활동에 대한 수요가 증가할 것으로 예상되며, 이는 관련 산업의 회복과 성장을 도모할 것으로 전망됩니다.
아래는 이러한 경향을 보여주는 자료 예시입니다.
위의 그래프는 2021년 이후로 해외로 출국하는 사람과 국내 여행 일수가 늘어나는 여행자 수가 다시 상승하는 추세를 보여주고 있습니다. 이러한 변화된 여행 환경에 적응하며 여행을 다시 시작하는 사람들은 새로운 여행지를 고민하거나 다른 사람의 여행이나 놀거리에 대한 궁금증을 가질 수 있습니다.
저희 프로젝트는 이러한 사용자들의 고민을 해소하고, 사용자의 추억을 공유하고 저장하는 공간을 제공하기 위해 기획되었습니다. 여행을 또는 놀이를 계획하기 전에는 두근거리는 마음으로 새로운 여행지를 고민하고, 여행이나 즐거운 시간의 여운을 남기며 즐기는 것을 돕고자 합니다.
프로젝트를 통해 사용자들은 여행이나 놀이를 즐기는 동안 추억을 저장하고 나누며, 개인의 행복한 시간을 두 배로 늘릴 수 있는 경험을 제공받게 될 것입니다. 이를 통해 여행에 대한 즐거움을 더욱 풍요롭게 누릴 수 있을 것으로 기대됩니다.
1. 코스 생성 :
회원은 자신이 원하는 장소들을 조합하여 놀거리 코스를 생성할 수 있습니다.
2. 그룹 :
회원은 함께하는 그룹을 생성하여, 그룹 내에서 코스를 공유하고 저장할 수 있습니다. 또한, 개인 그룹을 생성하여 혼자서도 코스를 관리할 수 있습니다.
3. 게시글 :
회원은 게시글 형식으로 자신의 코스를 다른 사용자와 공유할 수 있으며, 다른 사용자가 올린 코스도 조회할 수 있습니다.
4. 팔로우 :
회원은 다른 회원을 팔로우하여 그 회원이 올린 게시글을 조회하거나 관계를 형성할 수 있습니다.
추가적인 학습 내용 또는 관련 기술 설명 WIKI 바로가기
Plrecipe 상세정책
-
게시글
-
게시글에는 (1개 이상의 장소를 담은) 코스가 필수로 포함되어야 한다.
-
게시글 내용은 0글자 이상 작성되어야 한다.(내용 필수 아님)
-
게시글 이미지는 0개 이상 포함될 수 있다.(이미지 필수 아님)
-
게시글은 공개/비공개 설정이 가능하다.
- 그룹 게시물의 경우
- 공개 -> 모든 사람에게 공개 및 그룹에 추가
- 비공개 -> 그룹에게만 공개
- 그룹 게시물의 경우
-
게시글 수정은 게시글을 작성한 회원/(그룹 게시물의 경우)그룹원만 가능하다.
-
게시글 삭제는 게시글을 작성한 회원/(그룹 게시물의 경우)그룹원/관리자만 가능하다.
-
게시글 삭제의 경우 실제 DB에서 삭제되지 않고 삭제 일자가 업데이트 된다.
-> 삭제 일자가 업데이트 된 게시글은 페이지에서 보이지 않는다.
-
-
해시태그
- 게시글에는 해시태그가 0개 이상 등록되어야 한다.(해시태그 필수 아님)
- 이미 저장된 해시태그 중 원하는 태그가 없을 경우, 태그를 회원이 직접 등록할 수도 있다.
- 게시글의 해시태그는 10개까지 등록 가능하다.
-
회원
- 회원의 ID는 이메일 형식으로 중복될 수 없다.
- 회원의 비밀번호는 영어와 숫자를 같이 써야 하고 15자를 넘길 수 없다.
- 회원의 닉네임은 중복 불가능하다.
- 회원의 닉네임은 부적절한 닉네임일시 제재를 받을 수 있다.
- 회원등급은 일반회원과 관리자로 구분된다.
- 회원상태는 활성화/비활성화(임시정지, 영구정지)로 구분된다.
- 회원상태가 임시정지/비활성화일 경우에는 일반적인 기능 사용이 제한 되고 고객센터만 사용 가능하다.
- 회원이 탈퇴할 시에도 정보는 데이터베이스에 저장되어 있다.
- 전화번호는 반드시 기입해야 한다.
- 회원은 팔로우, 팔로워를 갖는다.
- 팔로워는 팔로우 하는 대상의 공개된 정보를 열람할 수 있다(회원이 속한 그룹, 회원이 작성한 게시물, 회원 닉네임)
-
그룹
- 그룹은 처음에 생성될 때 본인만 포함되어 있는(1인) 그룹이 생성된다. -그룹에 다른 회원을 초대할 시 회원ID로 초대한다.
- 그룹 이름을 따로 설정하지 않을 시 "(그룹을 생성한 회원 닉네임)의 그룹"으로 표시된다.
- 그룹에 구성원을 초대 했을 때 '초대 수락' 후에 그룹에 포함된다.
- 회원(본인)이 속한 그룹을 공개/비공개로 처리할 수 있다.
- 회원(본인)은 그룹을 (상단)고정할 수 있다.
- 그룹원은 (그룹 내 게시글 등록, 본인이 쓴 게시글 삭제, 게시글 수정(본인 포함 그룹원), 그룹 탈퇴, 그룹 내 게시글 댓글 작성) 권한을 갖는다.
- 그룹장은 그룹원의 권한을 포함해 그룹원 추방, 그룹 이름 수정, 그룹원 초대 권한, 그룹 공개 여부 권한, 그룹장 위임을 갖는다.
- 그룹장이 그룹을 탈퇴한 경우 두 번째로 그룹에 포함된 사람이 그룹장이 된다.
- 이미 초대한 그룹원이 수락 또는 거절을 하기 전(대기 중)인 경우, 재초대가 불가능하다.
-
코스
- 중복된 장소는 코스에 등록할 수 없음.
- 코스 블럭은 장소 카테고리별로 색깔이 매겨짐.
- 코스는 상단부터 쌓이고 갔던 장소는 재 방문 불가능
- 장소 데이터베이스에 존재하지 않으면 코스 작성하는 도중에 사용자가 장소 등록 가능
- 코스 만들고 사용자가 코스 이름 붙일 수 있음
-
장소
- 장소 카테고리(음식점, 카페, 문화, 액티비티, 산책, 기타)
- 외부 API에서 받아온 장소를 사용자가 적절한 카테고리를 붙여 장소 등록
- 장소 등록시 카테고리를 무조건 붙여야 함.
- 장소를 등록하기 전에 동일한 주소 또는 이름으로 이미 등록되어 있는 정보를 사용자에게 한번 확인 시키고 등록하는 절차로 진행(동일한 주소, 이름이 없는 경우 확인하지 않음)
- 장소 별점을 남길 때 간단한 한 줄 코멘트 작성 가능 (별점은 1 ~ 5개)
DDD 설계 과정
- 정책 추가
- 메모 추가(기능의 정확한 정의, 고도화 가능성)
- 게시글 / 게시글(부가기능) / 게시글 댓글 / 장소 / 회원 / 그룹 / 계정 정보
- Domain으로 분리
- Boundary(경계): 각 도메인 모델의 경계를 정의함. 이는 모델이 관리하는 데이터와 비즈니스 규칙을 나타냄.
- Relationships(관계): 다른 도메인 모델과의 관계를 정의함. 이는 모델 간에 어떤 종류의 통신이 필요한지를 보여줌.
- Shared Kernel(공유 커널): 두 개 이상의 도메인 모델 간에 공유되는 부분을 나타냄. 이는 각 모델이 특정 비즈니스 기능을 수행하는 데 필요한 공통 요소를 나타냄.
- Customer/Supplier Relationships(고객/공급자 관계): 서로 다른 도메인 모델 간에 발생하는 요청과 응답의 흐름을 나타냄. 이는 서로 다른 모델 간에 어떤 종류의 통신이 이루어지는지를 보여줌.
위의 4가지를 고려해서 Context Mapping
* Context Map
- 핵심 기능 우선 구현
- Root간 1:N, 1:1 관계 설정
DDL
CREATE TABLE `member_info` (
`member_id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
`member_email` VARCHAR(127) NOT NULL UNIQUE,
`password` VARCHAR(31) NOT NULL,
`member_name` VARCHAR(63) NOT NULL,
`member_nickname` VARCHAR(31) NOT NULL UNIQUE,
`member_number` VARCHAR(15) NOT NULL,
`join_date` VARCHAR(255) NOT NULL,
`withdrawal_date` VARCHAR(255) NULL,
`member_grade` ENUM('ROLL_MEMBER', 'ROLL_ADMIN') NOT NULL,
`member_status` CHAR(1) NOT NULL DEFAULT 'Y'
);
CREATE TABLE `post` (
`post_id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
`post_title` VARCHAR(255) NOT NULL,
`post_content` VARCHAR(255) NOT NULL,
`post_date` VARCHAR(255) NOT NULL,
`post_delete_date` VARCHAR(255) NULL,
`member_id` INT NOT NULL,
`course_id` INT NOT NULL,
`is_post_public` CHAR(1) NOT NULL DEFAULT 'Y',
`member_count` ENUM('ONE', 'TWO', 'MANY') NOT NULL,
`group_id` INT NULL
);
CREATE TABLE `plrecipe_group` (
`group_id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
`group_name` VARCHAR(255) NOT NULL,
`is_group_public` CHAR(1) NOT NULL DEFAULT 'Y',
`group_create_date` VARCHAR(255) NOT NULL,
`group_withdrawal_date` VARCHAR(255) NULL,
`group_comment` VARCHAR(255) NULL,
`group_status` CHAR(1) NOT NULL DEFAULT 'Y'
);
CREATE TABLE `follow_info` (
`follow_id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
`user_follow` INT NOT NULL,
`user_follower` INT NOT NULL,
UNIQUE KEY unique_follow_info(user_follow, user_follower)
);
CREATE TABLE `place_star` (
`star_id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
`star_point` INT NOT NULL,
`star_comment` VARCHAR(255) NULL,
`place_id` INT NOT NULL,
`member_id` INT NOT NULL,
UNIQUE KEY unique_place_star(place_id, member_id)
);
CREATE TABLE `place` (
`place_id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
`place_name` VARCHAR(127) NOT NULL,
`place_location` VARCHAR(255) NOT NULL,
`place_phone_num` VARCHAR(15) NULL,
`place_category_id` INT NOT NULL,
UNIQUE KEY unique_place (place_name, place_location)
);
CREATE TABLE `image` (
`image_id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
`image_location` VARCHAR(255) NOT NULL,
`image_name` VARCHAR(255) NOT NULL,
`post_id` INT NOT NULL,
`member_id` INT NOT NULL,
`group_id` INT NOT NULL,
`image_rename` VARCHAR(255) NULL
);
CREATE TABLE `course` (
`course_id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
`course_name` VARCHAR(127) NULL,
`member_id` INT NOT NULL
);
CREATE TABLE `group_member` (
`group_member_id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
`groupmember_sequence` INT NOT NULL,
`invite_state_id` ENUM('ACCEPT', 'WAITING', 'DENY') NOT NULL DEFAULT 'WAITING',
`group_id` INT NOT NULL,
`member_id` INT NOT NULL,
UNIQUE KEY unique_group_member (group_id, member_id)
);
CREATE TABLE `course_place` (
`place_course_id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
`place_id` INT NOT NULL,
`course_id` INT NOT NULL,
`place_sequence` INT NOT NULL
);
CREATE TABLE `place_category` (
`place_category_id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
`place_category_name` VARCHAR(63) NOT NULL
);
CREATE TABLE `hashtag` (
`hashtag_id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
`hashtag_title` VARCHAR(255) NOT NULL UNIQUE
);
CREATE TABLE `post_hashtag` (
`post_hashtag_id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
`hashtag_id` INT NOT NULL,
`post_id` INT NOT NULL,
UNIQUE KEY unique_post_hashtag (hashtag_id, post_id)
);
CREATE TABLE `post_like` (
`post_like_id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
`member_id` INT NOT NULL,
`post_id` INT NOT NULL
);
-- ALTER TABLE `member_info` ADD CONSTRAINT `PK_MEMBER_INFO` PRIMARY KEY (
-- `member_id`
-- );
ALTER TABLE `post` ADD CONSTRAINT `FK_plrecipe_group_TO_post_1` FOREIGN KEY (
`group_id`
)
REFERENCES `plrecipe_group` (
`group_id`
);
ALTER TABLE `post` ADD CONSTRAINT `FK_member_info_TO_post_1` FOREIGN KEY (
`member_id`
)
REFERENCES `member_info` (
`member_id`
);
ALTER TABLE `post` ADD CONSTRAINT `FK_course_TO_post_1` FOREIGN KEY (
`course_id`
)
REFERENCES `course` (
`course_id`
);
ALTER TABLE `follow_info` ADD CONSTRAINT `FK_member_info_TO_follow_info_1` FOREIGN KEY (
`user_follow`
)
REFERENCES `member_info` (
`member_id`
);
ALTER TABLE `follow_info` ADD CONSTRAINT `FK_member_info_TO_follow_info_2` FOREIGN KEY (
`user_follower`
)
REFERENCES `member_info` (
`member_id`
);
ALTER TABLE `place_star` ADD CONSTRAINT `FK_place_TO_place_star_1` FOREIGN KEY (
`place_id`
)
REFERENCES `place` (
`place_id`
);
ALTER TABLE `place_star` ADD CONSTRAINT `FK_member_info_TO_place_star_1` FOREIGN KEY (
`member_id`
)
REFERENCES `member_info` (
`member_id`
);
ALTER TABLE `place` ADD CONSTRAINT `FK_place_category_TO_place_1` FOREIGN KEY (
`place_category_id`
)
REFERENCES `place_category` (
`place_category_id`
);
ALTER TABLE `image` ADD CONSTRAINT `FK_post_TO_image_1` FOREIGN KEY (
`post_id`
)
REFERENCES `post` (
`post_id`
);
ALTER TABLE `image` ADD CONSTRAINT `FK_member_info_TO_image_1` FOREIGN KEY (
`member_id`
)
REFERENCES `member_info` (
`member_id`
);
ALTER TABLE `image` ADD CONSTRAINT `FK_plrecipe_group_TO_image_1` FOREIGN KEY (
`group_id`
)
REFERENCES `plrecipe_group` (
`group_id`
);
ALTER TABLE `course` ADD CONSTRAINT `FK_member_info_TO_course_1` FOREIGN KEY (
`member_id`
)
REFERENCES `member_info` (
`member_id`
);
ALTER TABLE `group_member` ADD CONSTRAINT `FK_plrecipe_group_TO_group_member_1` FOREIGN KEY (
`group_id`
)
REFERENCES `plrecipe_group` (
`group_id`
);
ALTER TABLE `group_member` ADD CONSTRAINT `FK_member_info_TO_group_member_1` FOREIGN KEY (
`member_id`
)
REFERENCES `member_info` (
`member_id`
);
ALTER TABLE `course_place` ADD CONSTRAINT `FK_place_TO_course_place_1` FOREIGN KEY (
`place_id`
)
REFERENCES `place` (
`place_id`
);
ALTER TABLE `course_place` ADD CONSTRAINT `FK_course_TO_course_place_1` FOREIGN KEY (
`course_id`
)
REFERENCES `course` (
`course_id`
);
ALTER TABLE `post_hashtag` ADD CONSTRAINT `FK_hashtag_TO_post_hashtag_1` FOREIGN KEY (
`hashtag_id`
)
REFERENCES `hashtag` (
`hashtag_id`
);
ALTER TABLE `post_hashtag` ADD CONSTRAINT `FK_post_TO_post_hashtag_1` FOREIGN KEY (
`post_id`
)
REFERENCES `post` (
`post_id`
);
ALTER TABLE `post_like` ADD CONSTRAINT `FK_member_info_TO_post_like_1` FOREIGN KEY (
`member_id`
)
REFERENCES `member_info` (
`member_id`
);
ALTER TABLE `post_like` ADD CONSTRAINT `FK_post_TO_post_like_1` FOREIGN KEY (
`post_id`
)
REFERENCES `post` (
`post_id`
);
- 유레카 서버와 유레카 클라이언트로 구성됨
- 유저는 게이트웨이를 통해 원하는 서비스와 매칭됨(Member, Group, Post, Place)
- 비밀번호 암호화 및 로그인 인증을 구현함(Spring Security 6 version 활용)
- 로그인 시, 토큰을 발급받아 이후 인증이 필요한 서비스에 접근 가능함(JWT(java web token) 활용)
- 장소 서비스는 API를 통해 장소 정보를 받아옴(외부 Api는 Kakaomap api 사용)
- 각 서비스끼리 통신하여 필요한 정보를 주고 받음
- (현재 DB는 하나의 DB를 사용함)
-
서비스 등록: 서비스 인스턴스가 시작될 때, 해당 서비스를 Eureka 서버에 등록.
-
서비스 검색: 클라이언트 애플리케이션이 다른 서비스 인스턴스의 위치를 검색. 이를 통해 클라이언트는 동적으로 서비스 위치를 찾아서 통신.
-
서비스 상태 감시: Eureka는 등록된 서비스 인스턴스들의 상태를 주기적으로 감시하고, 문제가 발생한 인스턴스들을 자동으로 감지하고 제거함.
Member
Login
Regist Member
Modify Member
Password Encryption
All Member Select
Select By MemberId
Withdraw Member
Post
Regist Post
Modify Post
Regist Post Like
Select All Post
Delete Post
Insert HashTag
Select Like By Post
Select Member Posts
Select HashTag By Post
Select Post By MemberCount
Select Post By Status
Place
Regist Place
Regist Star (To place)
Modify Star
Delete Place
Delete Star
Select All Place
Select Place By PlaceId
Select Place By Filter
Select Star By MemberId
Select Star By Place
Group
Regist Group
Invite Group
Modify Group
Delete Group
Accept Request
Select All Group
Select Group By Public Status
Withdrawal Group
팀 원 | 회고록 |
---|---|
배성민 | 주제는 '필요성'을 고려하여 프로젝트를 시작했으며, 팀원들과 함께 즐겁게 진행할 수 있는 측면도 고려했습니다. 프로젝트를 마이크로 서비스 아키텍처(MSA) 형태로 진행했으며, 이는 쉽지 않았지만 팀원들과의 교류를 촉진하고 서비스에 대한 이해를 높일 수 있었습니다. 완벽한 MSA를 구축하지 못했지만, 다양한 세분화 방식을 경험할 수 있었습니다. 백엔드 구현 기간의 제약으로 인해 모든 기능을 완벽하게 구현하지 못한 점이 아쉬웠지만, 이를 고도화하는 과정을 통해 더 나은 서비스를 제공하고자 하는 욕심이 있습니다. 다양한 기술 스택을 활용하면서 이전에 학습한 내용을 복습할 수 있었고, 특히 MyBatis(조회)와 JPA(입력, 수정, 삭제)를 통한 데이터베이스 처리 방법을 활용했습니다. 또한 유레카 서버와 클라이언트를 통해 게이트웨이를 설정하고 다른 서비스를 호출하는 방식을 적용했는데, 이를 통해 실제 회사에서의 적용 사례를 학습할 수 있었습니다. 제가 맡은 역할 중에서는 암호화와 아키텍처 제작이 기억에 남습니다. Spring Security의 지속적인 업데이트로 인해 암호화 부분이 어려움을 겪었고, MSA를 적용하면서 토큰 방식(JWT)을 통한 인증 및 인가가 어려웠습니다. 아키텍처는 정해진 형식이 없었지만 실제 사례와 성공 사례를 참고하여 구성했으나, 더 많은 기능을 고려한 아키텍처를 구성하고 싶은 아쉬움이 남았습니다. 팀 프로젝트는 긍정적인 분위기 속에서 팀원들은 각자의 역할을 잘 수행하고 의견을 나누어주어 프로젝트를 성공적으로 이끌어낼 수 있었던 것 같습니다. 이러한 이유 때문인지 프로젝트 이후에도 더 발전하고자 하는 욕심이 생겼으며, 새로운 기술과 도구에 대한 학습에 대 흥미를 느끼기도 했습니다. 이번 프로젝트에서 부족한 부분과 궁금한 부분을 보완하고 발전시키기 위해 꾸준히 노력해봐야겠다는 생각도 들었습니다. |
한소혜 | 이번 백엔드 프로젝트를 진행하며 이전보다는 생소하지 않은 주제로 진행하게 되어서 과정을 좀 더 즐길 수 있었습니다. 그리고 이전의 경험을 토대로 미리 장소 블럭과 코스 등 주요한 개념을 팀원들과 맞춰가며 좀 더 수월하게 진행할 수 있었습니다. jsp, servlet을 이용하여 백엔드 프로젝트를 진행한 적이 있었는데, 스프링을 활용해 개발을 진행하니 같은 시간을 사용해 더 제대로 된 기능을 구현할 수 있어 신기했습니다. 또한 조회는 MyBatis, 삽입/수정/삭제는 JPA를 통해 구현하며 다양한 방식을 활용하며 각 장단점을 직접 느끼고 어떻게 하면 잘 활용할 수 있을지 고민해볼 수 있던 시간이었습니다. 이번 프로젝트에서 가장 좋았던 점은 msa 방식을 배우고 각 서비스를 나눠서 구현해볼 수 있었다는 것입니다. 유레카 서버와 클라이언트를 이용하고 게이트웨이까지 직접 설정해볼 수 있었던 의미있는 경험이었다고 생각합니다. feign client를 사용해 다른 서비스와 통신하고 정보를 받아오는 과정도 뿌듯하고 재밌었습니다. 이전 프로젝트보다 더 발전된 모습으로 이번 구현을 통해 팀원들과 함께 고민하고 프로젝트를 완성할 수 있어서 좋았습니다. |
윤재은 | 놀거리 코스를 제공하는 커뮤니티를 주제로 하는 백엔드 프로젝트를 하며 수업에서 배웠던 MyBatis의 remix 방식을 채택한 다중열 조회, JPA를 사용한 CRUD 에서 많은 오류를 겪으며 myBatis와 JPA의 장단점을 알 수 있었고 resultMap 작성, 비즈니스 로직등 아직 확실히 알지 못했던 것을 실제로 사용해보며 깨우칠 수 있어 좋았습니다. 또한 Eureka cloud를 사용하여 서비스를 MSA로 나누어 server와 gateway를 통해 연결 후 DB에서 join을 이용해 값을 가져오는 것이 아니라 feign client를 사용해 주고받는 기능을 적용해보며 흥미를 많이 느꼈습니다. |
조수빈 | 기획 단계에서 기존 서비스와는 차별성이 있되 어느정도 참조할 레퍼런스도 있는 서비스를 기획하는 게 생각보다 어렵고 시간이 오래 걸리는 과정이었습니다. 팀원들이 각자 사용하면서 만족했던 서비스와 아쉬웠던 점을 공유하며 적합한 주제를 찾을 수 있었고, 이후 기능 구현 단계에서 시간이 오래 걸리더라도 기획 단계를 꼼꼼하게 하는 것이 얼마나 중요한지 깨달을 수 있었습니다. 또한, 구현할 서비스에 대해 사소한 개념이라도 명확하게 한 상태에서 기능 구현을 시작해야 한다는 점도 배울 수 있었습니다. 이전 프로젝트에서는 다루지 못했던 서버 및 통신 이슈들을 직접 다뤄보며 수업시간에 배웠던 내용을 직접 구현하는 과정을 통해 자연스레 복습하며 체화할 수 있는 좋은 경험이었습니다. MSA 방식으로 팀원별로 한 가지 기능을 맡아 구현하며 책임감을 가지고 작업할 수 있었으며, 오류가 발생했을 때는 본인의 기능이 아니더라도 서로 의견을 공유하며 제대로 된 협업을 경험할 수 있었습니다. 중간객체가 없는 기능을 맡아 직접 중간객체 구현 및 통신을 하지 못했다는 아쉬움이 있어 다음 프로젝트에는 양이 부담이 되어도 구현할 분량이 더 많은 기능을 맡아보고 싶습니다. |
김재현 | 처음에 무슨 주제를 할지 토론하는 시간도 즐거웠고, 커플 앱 아이디어로 시작해서 저희 PLRECIPE 프로젝트까지 오게된 과정도 굉장히 재밌었습니다. 이번 백엔드 프로젝트를 진행하며 그동안 수업헤서 배웠던 Mybatis 방식으로 조회 기능을 구현하고 테스트 해보며, 특히 xml 파일에서 수많은 resultMap 오류를 접하고 sql 쿼리문을 복습할 수 있었던점이 좋았습니다. 또한 JPA 방식으로 C(R)UD 기능또한 구현하고 테스트하며 mybatis 방식과 어떤 차이점이 있는지 명확하게 알 수 있었습니다. 다만 제가 맡은 그룹 서비스 기능에서 db에서 조인을 통해 다른 서비스의 값데이터를 불러오는게 아닌 완벽하진 않지만 준 msa 방식을 통해 다른 서버에서 feignclient를 통해 불러오고 싶었는데 그 기능은 기한내 못해서 좀 아쉬웠습니다. 이 프로젝트를 프론트 개발 단계까지 이어나간다면 더 고도화 해보고 싶습니다. 다들 정말 고생많으셨습니다!! |