본문 바로가기

SpringBoot/구현 고민들12

[Spring] 단일 서버 환경에서 API 기능 동시성 문제 고려하기 2024년 상반기에 진행했던 프로젝트를 2025년 상반기(현재)에 다시 훑어보며 과거에는 신경쓰지 못했던 관점이 무엇이었는지 돌아보고 있는 시간을 가지고 있다. 내가 선정한 여러 관점 중 첫번째 관점이 "동시성 Concurrency" 문제였다. 동시성 문제 상황layered-architecture 상에서 studyRelationService는 교내 재학생들을 위한 스터디 "지원 현황" 이력을 관리하는 파트이다.내가 수정을 해야겠다고 느꼈던 부분은 아래 api들이었다.1. 스터디 지원 취소 API : studyRelation의 status를 CANCEL로 업데이트 한다2. 스터디 게시자가 지원자들을 수락/거절하는 상태 업데이트 API : 지원자의 studyRelation의 status를 ACCEPT || .. 2025. 3. 10.
[Spring] 콘솔 로그를 어떻게 잘 관리할 수 있을까 개발을 하다보면 트러블 슈팅을 해야할 일이 정말 많이 생긴다. 버그를 해결하는 과정에서 개발 테스트 상 스프링부트를 재실행하면 콘솔 로그가 초기화되면서 직전 로그 내역을 다른 곳에 기록해두지 않는 이상 확인을 할 수 없게 된다. 이뿐만 아니라 프론트에서 백엔드 서버로 API 요청 시 에러 사항에 대해서 확인하고 싶을 때 ec2에 접속해서 docker-compose logs(tail 옵션 붙여서 최근 로그를 바로 확인)를 통해 해당 에러가 언제 생겼는지 훑어야 하는 불편함이 존재한다. 따라서 로그의 영구적인 관리 중요성을 느끼고 WHOA 서비스에 (이슈 링크) 적용해보고자 했다. 먼저 콘솔 창에 로그를 출력할 때 System.out.println을 쓸 경우 성능 저하가 상당하기 때문에 loggerFacto.. 2024. 12. 14.
[Spring] Widget 구현 방안 보호되어 있는 글 입니다. 2024. 9. 29.
[Spring] ElasticSearch 검색 필터링 API 고도화 고민 : 쿼리 라이브러리 비교 추석 연휴를 제외하고 9월 12일부터 elasticSearch 기반의 조회 API(검색 필터링 기능) 작업을 시작하여 이번주(9월 3주차) 금요일까지 12일, 13일, 19일, 20일 elasticDB 습득 과정부터 실제 개발 과정까지 포함해 총 4일에 거쳐 드디어 전체 조회 시 requestParam으로 받은 여러 필드에 대해서 null 조건까지 포함하여 필터링을 하는 로직을 드디어 구현해냈다. 내가 ElasticSearchRepository, ElasticsearchClient, ElasticsearchOperation을 도입한게 처음이었던 것과 관계 없이 주어진 일정 기간 안에 구현을 끝냈어야 했고 앞으로 구현해야 할 부분의 마감 기간까지 고려했을 때 20일까지는 적어도 이 파트를 끝냈어야 차질이 .. 2024. 9. 22.
[Spring] SpringBoot Actuator를 왜 써야하고 어떻게 잘 써야할까 "지금은 잘 돌아가니까 문제 없다"라는 접근은 문제가 발생하기 전까지 문제를 방치하는 마음가짐이기 때문에 이전에 이 게시글에서 언급한대로 EC2 내부 문제를 겪고 CloudWatch를 통해 모니터링을 하고 있지만 Memory check뿐만 아니라 전반적인 모니터링을 springboot 환경에서 할 수 있는 방법은 없을까 찾아보다가 SpringBoot Actuator를 적용해봐야겠다고 생각(PR 링크)했다.  Spring Actuator란?Spring Actuator는 아래와 같이 build.gradle에 dependencies로 추가만 해주면 즉각 사용할 수 있기 때문에 SpringBoot 프레임워크를 바탕으로 백엔드 API를 구현할 경우 서버 모니터링 관리를 용이하게 할 수 있게 해준다. // Actu.. 2024. 8. 24.
[Spring] GET 요청 쿼리 스트링이 많을 경우 @RequestBody vs @ModelAttribute 프로젝트에서 검색 필터링 Nullable 조건의 API를 개발(구현된 PR 링크)하면서 GET mothod와 @RequestBody 어노테이션을 같이 썼었다. HTTP GET with payload body는 RFC 7231 스펙에 공식적으로 명시(공식 문서 링크)되어있듯이 이 둘의 양립이 허용되었으나 일부 클라이언트에서는 GET 요청과 함께 body를 보낼 경우 이를 무시하거나 POST로 바꿔버리는 문제가 있을 수 있다는 것을 알게 되었고 실제 프론트 친구로부터 GET + body 요청이 리액트 개발환경 상에서 안된다는 연락을 받게 되었다. 문제 상황위에서 간략하게 언급했듯이 기능 자체가 "필터링 검색"이기 때문에 프론트에서 서버로 보내야 하는 필드 값이 많아서 GET 요청임에도 request dto .. 2024. 8. 23.
[Spring] Facade Pattern 적용 계기 및 이유 해당 PR(퍼사트 패턴 적용 시도한 링크)을 통해서 Facade Pattern을 처음 적용해보게 되었다. 이 디자인 패턴을 도입하기까지의 고민 과정을 기록하고자 한다. 도입 배경내가 퍼사드 패턴을 도입하려는 프로젝트를 간략하게 소개하고자 한다. 그동안 IT 분야로 오게 되면서 컴퓨터공학과 학생으로서 현재 다니고 있는 대학교 재학생들을 위한 서비스를 졸업하기 전에 한 번은 꼭 개발해서 학생들이 이 서비스를 이용하는 모습을 정말 정말 보고 싶었다. 그러기까지 서로 다른 주제의 프로젝트들을 진행하면서 시도하였으나 출시 및 운영까지 이어지기가 쉽지 않았는데 이 프로젝트(출시 링크)에서 소망을 이룰 수 있게 되어서 이거를 많이 애정한다. 주제가 재학생들을 위한 네트워킹 서비스이며 그 중 선후배, 동기 매칭을 도와.. 2024. 8. 7.
[Spring] AWS S3 Base64 인코딩된 이미지 처리 과정 고민 및 구현 과정 백엔드에서 이미지를 처리하는 과정은 정말 다양하다. 내가 실제로 구현해 본 방법은 아래와 같다.1. AWS S3 presigned url 발급 2. List 형식의 업로드3. base64 인코딩된 List을 디코딩하여 S3에 업로드  이 게시글에서는 3번을 적용하기까지 과정을 기록하고자 한다.   PresignedUrl의 trade-off 고민 이번 상반기에 진행했던 프로젝트 중 두 개의 프로젝트에서 내가 이미지 처리를 맡게 되었었다. 처음에는 presignedUrl을사용함으로써 제한된 시간 동안만 유효한 url을 발급하여 서버에서 직접 이미지 업로드 및 다운로드 요청을 하는 것이 아니라 프론트에서 직접 S3로 다이렉트 업로드를 함으로써 서버 부하 뿐만 아니라 네트워크 전송 비용을 줄이고자 하였다. 또한.. 2024. 7. 12.
[Spring] soft delete와 임시 저장 구별 창업팀에서 봉착한 구현 고민!현재 상황임시 저장을 하는데 DB 테이블의 deleted 필드 (soft delete)를 사용하여 구현을 한 상황이었다. private boolean deleted; 를 통해 작성 완료 여부를 나타내고 작성 완료를 누르지 않고 중간에 나가버리면 임시 저장이 가능. 소프트 삭제가 이뤄지는 방식이다. @Getter@NoArgsConstructorpublic class PromiseCatchRequestDto { private EventType event; //종목 private Integer recruitmentNumber; // 모집 인원 private RequirementType requirement; // 참여 조건 private LocalDateTim.. 2024. 6. 28.
[Spring] AWS S3로 다중 이미지 업로드 한 번의 API 호출로 프론트에서 여러 이미지 파일을 넘겨주면 한 번에 S3로 업로드할 수 있는 방법(PR 링크)을 알아보자 문제 상황 : PresignedUrl의 한계내가 지금 해야 하는 것은 Bouquet 엔티티 객체가 등록되고 난 뒤 이 객체와 일대다 연관 관계를 맺고 있는 BouquetImage 객체에 프론트에서 요청한 이미지의 url(fileName)을 저장하는 것이다. 기존에 presignedUrl로 구현하여 이미지를 서버 측에서 관리하는 것이 아니라 프론트에서 바로 s3에 접근할 수 있게 권한을 줌으로써 서버 과부하를 막고자 하였다. 하지만 bouquet create 시 유저가 최대 3개의 이미지를 업로드할 수 있는데 매번 프론트에서 POST Bouquet 객체 생성 성공 시 200 OK 이.. 2024. 5. 26.
[Spring] JPA Specification을 통해 다중 검색 조건에 따른 검색 API 구현(feat. 메소드 체이닝) 검색 API를 구현하는 방법에는 내 나름 대로 생각해본 여러 가지 방법이 있다.1. 백엔드에서 전체 data를 다 주고 프론트에서 contains과 같은 개발 언어 내장함수를 이용해서 프론트에서 처리2. jpa repository로 like containing을 이용해서 원하는 조건의 쿼리를 날리기3. elastic search 검색 엔진을 이용하기 위 세가지 중에서 1번은 기능 구현 자체를 프론트에게 너무 위임하여 불필요한 data 까지 전달할 우려가 있어서 사용하지 않았고 elastic search는 단순 게시글 검색 기능이기 때문에 기능에 비해 큰 툴을 사용한다는 점 때문에 지양하였고 2번 방법을 통해 containing을 처음에 이용하려고 하였다.  그러나 검색 조건 record request D.. 2024. 5. 19.
[Spring] 무한 스크롤에서 Page vs Slice의 차이(feat. Slice 구현 코드) 프로젝트에서 내가 맡은 기능 이슈에서 게시글 목록 전체 조회 시 무한 스크롤 구현이 있었다. 작년에 프론트로 개발을 처음 시작했었을 때 무한 스크롤의 경우 백엔드에서 전체 데이터를 다 주면 안드로이드에서 recyclerView를 이용해서 무한스크롤을 구현했었는데 올해부터 백엔드 개발을 시작한 이래로 2월에 기본기를 다지기 위해 다른 프로젝트에서 CRUD를 맡다가 지금은 백엔드 입장이 되어서 백엔드 단에서 이 기능을 맡게 되어 감회가 새롭다. 백엔드로서 처음 맡는 기능인 만큼 단계적으로 진행하고자 무한 스크롤 없이 200OK가 응답되도록 전체적인 게시글 GET 요청에 대한 코드 설계는 완료를 해서 feature/#189 (이슈 번호) 브랜치에 push를 해둔 상황이고(엔티티 3개를 거쳐야 해서 구현이 재밌.. 2024. 5. 18.