🤔 링북은 어떤 서비스인가요?
• 나만의 북마크 폴더를 생성해 북마크를 손쉽게 저장하고 관리할 수 있습니다.
• 크롬 익스텐션을 통해 편리한 접근이 가능합니다.
• 자신의 북마크 폴더를 공유하고 다른 사용자들의 북마크 폴더를 열람, 스크랩할 수 있습니다.
• 제목 혹은 태그별로 인기 북마크 폴더, 또는 최신 북마크 폴더를 검색할 수 있습니다.
⚙️ 프로젝트 구조
.png?table=block&id=1290bde4-14c2-4e3d-9cdb-132de9391d3a&cache=v2)
🛠 무엇을 사용해 만들었나요?
🦋 FrontEnd
Language
TypescriptFramework
NextJSLibrary
React, ContextAPI, Recoil, React-hook-form, React-query, EmotionCommunication
Notion, Discord, SlackDesign
FigmaUI Test
Storybook🐳 BackEnd
구분 | 이름 | 사용한 이유 |
Language | Java 11 | - 조직에게 가장 익숙하고 현업에서 많이 사용하는 LTS 버전
- Lambda & Stream 기능 지원 |
FrameWork | Spring Boot 2.7.2 (REST API) | - 조직에게 가장 익숙한 Framwork
- Spring Framework가 제공하는 다양한 도구 사용 가능 |
ㅤ | Spring Data JPA | - 직관적인 객체지향 코드 작성 가능 : 비즈니스 로직에 집중
- 재사용 및 유지보수 편리성 증가 : 특정 DB에 한정되지 않아 DB 마이그레이션 용이 |
ㅤ | Spring Security(with JWT) | - Stateless한 인증, 인가 구현 가능
- 리프레시 토큰을 사용해 액세스 토큰의 짧은 유효기간 보완 |
DataBase | MySQL | - 조직에게 가장 익숙한 데이터 베이스
- 무료로 사용 가능 + Update 성능 우수 |
ㅤ | H2 | - 독립적인 DB 환경에서 테스트를 수행하기 위해 사용 |
Test | JUnit 5 | - 대표적인 Java 테스트 프레임워크 |
ㅤ | Jacoco | - 테스트 커버리지 체크를 위해 사용 |
Server | AWS EC2 | - 쉬운 접근성, 편리한 관리 |
ㅤ | NGINX | - Tomcat 앞단에서 Spring 설정 없이 SSL 인증을 적용하기 위해 사용 |
Infra | AWS RDS(MySQL) | - 유연한 인스턴스 제공 및 스토리지 확장 가능 |
ㅤ | AWS S3 | - 효율적인 정적 파일 관리 |
CI/CD | GitHub-Action | - GitHub 과 편리한 연계 가능 |
ㅤ | Docker | - 서버 migration 편리성 추구 |
Documentation | REST Docs | - 테스트 성공 후 API 문서 작성 가능
- 프로덕션 코드와 분리 추구
- 배포 시 웹으로 편리한 접근 가능 |
ㅤ | Notion | - 효율적인 문서화 & 협업 도구 |
Communication | Slack | - 텍스트 기반 커뮤니케이션 수단으로 사용 |
ㅤ | Discord | - 음성, 화상 회의에 사용 |
Project Management | GitHub Project/Issue | - Github Flow를 이용한 CI 파이프라인 구축
- Milestone 으로 프로젝트 일정 및 형상관리 |
🐛 개발 과정에서 어떤 이슈가 있었나요?
🦋 FrontEnd
🐳 BackEnd
Security
이슈 | 해결 방법 |
WebSecurityConfigurerAdapter deprecated 이슈 | 기존의 상속 받아 오버라이딩하는 방식에서 Bean으로 등록하는 방식으로 변경 |
JWT 필터에서 예외 발생 시 스프링 컨테이너에서 예외 처리 불가 | JWT 필터의 예외를 처리하는 필터를 구현하여 JWT 필터 앞에 배치 |
이메일 인증시, 인증된 이메일 검증 이슈 | 세션을 통해 정해진 시간동안 인증된 이메일의 정보를 저장하고 회원가입시 해당 이메일을 검증한다. |
Feature
이슈 | 해결 방법 | 개선할 점 |
태그로 폴더 검색 시, JPQL에서 FETCH JOIN 과 ON 을 함께 쓰면 DB상태와 일관성이 깨지는 문제 | 서브쿼리를 사용하여 해당 태그를 가지는 폴더들의 id들을 다중열로 가져오고 IN 과 FETCH JOIN 을 사용해 해결 | 서브쿼리는 DB 성능 측면에서 지양되므로 개선 필요 |
프론트 측에서 에러가 어떤 Entity 에서 발생했는지 알 수 없는 문제 | 엔터티별로 에러코드 구간을 나누어( -1XX : 사용자, -2XX : 폴더 등) 에러 객체를 body 에 담아 응답 | ㅤ |
태그 구조 계층화를 위한 데이터베이스 설계 및 유효성 체크 이슈 | 확장가능성을 위해 루트태그와 서브태그의 테이블을 분리해 연관관계를 맺고
Enum 타입으로 유효성 검사를 구현해 매번 DB 에서 조회하는 과정을 생략 | 데이터베이스와 Enum 타입 싱크 관리의 어려움 개선 필요 |
JPQL에서 일대다 FETCH JOIN 을 여러개 해야할 때 JOIN 으로 처리되어 1+N 문제 발생 + Limit 없이 전체를 메모리에 올려 Pagination 수행 : MultipleBagFetchException 문제 발생 | default_batch_fetch_size 를 통해 설정한 사이즈만큼 메모리에 불러와 IN 쿼리로 처리하여 메모리 낭비 해결 + 1+N 문제를 1+1 로직으로 대체 | ㅤ |
RequestDTO 와 Request Body값이 Jackson으로 매핑될 때 Enum 타입에 별칭이 있는 경우 Mapping 오류 발생 | @JsonCreator 를 통해 Custom 매핑 함수를 구현하여 해결 | ㅤ |
API 단위 설계시 비즈니스 로직과 코드 재사용성 중 어떤 것을 우선할 것인지에 대한 의견 충돌 | API 구조는 사용성을 높이기 위해 비즈니스 로직에 맞추고, 코드 재사용성은 그 Controller 밑단에서 최대한 확보하는 방향으로 설계 수정 | ㅤ |
Deploy
이슈 | 해결 |
Docker 를 이용해 Spring Application 과 NGINX 를 컨테이너화 하면서, 컨테이너 간 데이터 공유가 정상적으로 이루어지지 않는 이슈 발생 | Docker 컨테이너의 특성을 명확히 파악하지 못한 채 사용해서 발생한 문제. Docker 컨테이너가 자체적으로 사용하는 메모리 공간이 있음을 인지 후 해당 공간에 필요한 데이터를 전달하는 파이프라인을 추가함으로써 해결 |
📘 기타 자료
프로젝트 기획 문서API 명세서🦋 FrontEnd 기타 자료
🧑💻 누가 만들었나요?
팀원명 | 분야 | 프로젝트 담당 역할 | Github |
김동언 | FE | ㅤ | ㅤ |
민상기 | FE | ㅤ | ㅤ |
유용상 | FE | ㅤ | ㅤ |
정지영 | FE | ㅤ | ㅤ |
김수미 | BE | - CI/CD 파이프라인 구축
- Github 개발 환경 구축
- 프로젝트 일정 및 형상 관리 | |
이수연 | BE | - CI/CD 파이프라인 구축
- 폴더, 북마크, 태그 CRUD API 개발
- 스크랩 API 개발 | |
이일환 | BE | - ERD 설계, Entity 작성
- Spring Security, JWT 이용 인증/인가 개발
- 태그로 폴더 검색 API 개발 | |
이창호 | BE | - 댓글 CRUD API 개발
- 좋아요 CRUD API 개발
- 검색 API 개발
- AWS 인스턴스 관리 | |
최연호 | BE | - ERD 설계, Entity 작성
- Spring Security, JWT 이용 인증/인가 개발
- 이메일 인증 API 개발 |