Tiny Star

프로젝트 32

[뉴스 요약] 로그인 구현 (Spring Security ,JWT Token)

전체 흐름프론트에서 로그인 요청(`login`)을 보내면 백엔드는 이를 처리해 `accessToken`, `refreshToken`을 발급하고, 클라이언트는 이를 저장한 뒤 홈 화면으로 이동합니다. 이후 홈 페이지에서 사용자 정보 요청(`me`)을 다시 보내 사용자 정보를 렌더링합니다. AuthController로그인 요청 처리@PostMapping("/login")public ResponseEntity login(@RequestBody LoginRequest request) { LoginResponse loginResponse = authService.login(request); return ResponseEntity.ok().body(loginResponse);}프론트에서 사용자 ID..

[뉴스 요약] SpringBoot + React 이메일 인증 기반 회원가입

이메일 인증을 포함한 회원가입 기능을 구현했다.단순한 입력폼과 회원 저장이 아니라, 인증 흐름과 사용자 경험까지 고려한 구조로 만들고자 했다.이 글에서는 프론트와 백엔드 양쪽에서 회원가입 기능이 어떻게 동작하는지 전체 흐름을 정리해봤다. 전체 흐름사용자가 이메일을 입력하고 인증코드를 요청한다. (`/send-code`)인증코드가 메일로 전송되고, 서버는 Redis에 인증코드를 저장한다.사용자가 인증코드를 입력해 검증한다. (`/verify-code`)인증이 성공하면 Redis에 "인증 완료" 상태를 저장한다.닉네임/비밀번호를 입력하고 가입을 요청한다. (`/signup`)서버는 Redis 인증 여부를 확인하고, DB에 사용자 정보를 저장한다./send-code /verify-code /signup ..

[뉴스 요약] 요청 제한 + 로그 기록 (Redis + Kafka)

뉴스 요약 기능을 혼자 만들면서, 나중에 사용자에게 공개했을 때를 대비해 OpenAI API 호출에 제한을 둘 필요가 있다고 판단했다. 처음에는 프론트엔드에서 쿠키 기반으로 하루 5회 제한을 두는 식으로 간단하게 처리했지만, 브라우저나 기기를 바꾸면 무력화되는 구조라 한계가 뚜렷했다.그래서 이번에 요청 제한을 백엔드 Redis로 이전하고, 동시에 요청 이력을 Kafka를 통해 비동기로 DB에 저장하는 구조를 추가했다. 아직 나 혼자만 사용하는 서비스이긴 하지만, 구조를 미리 잘 설계해두면 나중에 트래픽이 생겼을 때 대응하기 수월할 것 같았다. 전체 구조요청이 들어오면 Redis에서 하루 5회 제한을 검사하고, 통과한 경우 GPT 요약 처리를 진행한다. 요약 결과는 DB에 저장하고, 동시에 요청 이력을..

[뉴스 요약] REST API 예외 응답 처리

왜 지금? 기능 구현에 집중하다 보니 예외 처리는 항상 뒷전으로 밀리곤 했다.그러다 보니 코드 곳곳에서 쓸데없는 분기 처리나 중복 조건문이 생기고, 전체 흐름이 점점 복잡해지기 시작했다.이런 구조가 쌓이면 결국 나중에 대대적인 리팩터링이 불가피해질 것 같다는 생각이 들어, 이번에는 예외 처리 구조부터 먼저 정리하고 들어가기로 했다. 구조 전체적인 예외 처리 흐름은 복잡하지 않다.핵심은 전역 예외 핸들러에서 원하는 형식으로 에러 응답을 통일해주고, 각 에러 상황에 맞는 에러 코드를 enum으로 정의해서 재사용하는 구조다.이렇게 구성하면 컨트롤러나 서비스 레이어에서는 `throw new CustomException(...)` 한 줄로 예외를 던질 수 있고, 핸들러에서는 이를 받아 `status`, `co..

[뉴스 요약] AI 중복 요청 분기 처리 (Database 구성)

뉴스 요약 결과 재사용을 위한 캐싱 설계 OpenAI API를 연동해 뉴스를 요약해주는 기능을 구현하다 보니, 같은 기사를 반복 요청하는 경우가 자주 발생했다. 처음엔 단순하게 매 요청마다 API를 호출했지만, 비용과 응답 속도 측면에서 비효율이 느껴졌다.“같은 기사에 같은 프롬프트로 요청했다면, 이전에 요약했던 결과를 재사용할 수 없을까?” 이런 고민에서 시작된 캐싱 구조를 정리해본다. 문제 인식 OpenAI API는 호출 횟수에 따라 비용이 발생한다.또, 뉴스 요약은 길이에 따라 평균 3초 이상의 응답 지연이 발생하는 경우도 많다.같은 기사에 대해 여러 번 요약을 요청하는 구조는 비효율적이었고,결국 캐싱을 고려하게 되었다. 설계 방향 요약 결과를 캐싱하려면, “어떤 기사”에 “어떤 프롬프트로” ..

[뉴스 요약] Swagger, REST Docs 적용

이번 프로젝트에서는 API 문서를 자동화하고 공유하기 위해 Swagger와 Spring REST Docs를 모두 적용해봤다. 둘 다 장단점이 명확했지만, 결론적으로는 REST Docs를 중심으로 사용하게 되었다. 이 글에서는 두 방식의 차이와 실제 적용 후 느낀 점, 그리고 각각의 사용법을 간단히 정리한다. 두 방식의 차이 비교 항목 Spring REST Docs Swagger (Springdoc/OpenAPI) 문서 생성 방식테스트 기반 (MockMvc 등)코드 기반 애너테이션정확성실제 응답을 기반으로 생성됨애너테이션 기반 → 실제 응답과 다를 수 있음의존성Asciidoctor + restdocs 필요springdoc-openapi 또는 springfox목적배포용 정적 문서개발자 UI 테스트용..

[뉴스 요약] 프론트 (Vite + React)

계획사용자가 뉴스 URL을 입력입력된 URL을 백엔드로 POST 요청결과 받아서 요약 결과 보여줌비로그인 상태에서 일 5회 요청 제한 Vite + React 선택Vite + React는 빠른 개발, 직관적인 설정, 좋은 확장성 때문에개인 프로젝트나 MVP 개발에 현 시점에서 가장 합리적인 프론트엔드 구조라고 한다.💡 React 프로젝트에서 MVP라면?View: React 컴포넌트Model: API, 상태관리Presenter: 컴포넌트 외부 로직 (예: useCase, service 함수) 역할 설명 Model데이터와 비즈니스 로직 (API 호출, DB 등)ViewUI (사용자에게 보여지는 화면)PresenterView와 Model을 연결하고 비즈니스 로직을 수행하는 중간 계층MVP는 생소해서 찾아..

[뉴스 요약] 백엔드 (Jsoup 파싱 + ChatGPT AI 연결)

Jsoup(JAVA HTML parser)jsoup 는 실제 HTML 및 XML 작업을 간소화하는 Java 라이브러리입니다. DOM API 메서드, CSS 및 xpath 선택자를 사용하여 URL 가져오기, 데이터 파싱, 추출 및 조작을 위한 사용하기 쉬운 API를 제공합니다. [링크] public NewsResponse parse(String url) { try { if (!url.startsWith("https://n.news.naver.com/")) throw new RuntimeException("네이버 뉴스가 아닙니다."); Document doc = Jsoup.connect(toPrintUrl(url)).get(); String title = doc.s..

[뉴스 요약] AI API를 이용한 뉴스 요약 프로젝트 기획

📄 뉴스 요약 및 분석 서비스사용자 입력 URL 기반 GPT 요약/분석 자동화 시스템Frontend: React + Vite / Backend: Java + Spring Boot 1. 목표사용자가 입력한 뉴스 URL을 기반으로 본문 크롤링OpenAI GPT API를 통해 기사 요약, 주제 분류, 키워드 추출프론트엔드에 요약 결과를 시각화하여 출력 2. 전체 시스템 아키텍처 3. 기능 명세✅ 프론트엔드 (React)기능 상세 내용URL 입력창사용자 입력 받기 (뉴스 기사 URL)로딩 상태 표시분석 요청 중 상태 표시결과 표시요약, 주제, 키워드 뱃지 형태로 시각화에러 처리잘못된 URL/서버 오류 메시지 표시✅ 백엔드 (Spring Boot)기능상세 내용/analyze-url APIPOST 요청 → UR..

[대용량 이관] DB 성능 튜닝 (InnoDB Buffer Pool)

300만 데이터가 있는 테이블의 count만 했을 뿐인데 20초 이상 소요되는 문제가 발생했다.[MariaDB 최신 버전으로 컨테이너 생성]만 하고 그 외 설정을 하지 않았기 때문에 설정을 추가해보려고 한다. .cnf 설정# InnoDB 설정innodb_buffer_pool_size = 2Ginnodb_log_file_size = 512Minnodb_log_buffer_size = 64Minnodb_flush_log_at_trx_commit = 2innodb_flush_method = O_DIRECTinnodb_io_capacity = 2000innodb_file_per_table = 1 항목설명 innodb_buffer_pool_size테이블, 인덱스, row 데이터를 메모리에 캐싱데이터를 디스크에서..

top