💻 프로젝트/트러블 슈팅

[QRoad]PDF 기반 publication 업로드 구조 개선기 - 3편: Spring Boot 최소 구현

SoloQuest 2026. 2. 11. 11:56

이 글은 「PDF 기반 publication 업로드 구조 개선기」 시리즈의 3편입니다.

(1편) 기존 구조의 문제점 → (2편) S3 presigned URL 설계 → (3편) Spring Boot 구현

 

앞선 글에서

  • 왜 기존 텍스트 기반 구조가 한계였는지
  • 왜 서버가 파일을 직접 받지 않는 구조를 선택했는지

를 정리했다.

이번 글에서는 그 설계를 바탕으로
Spring Boot에서 실제로 어떤 API를 만들었는지,
그리고 구현하면서 중요했던 포인트들을 정리해보려고 한다.


구현 목표 다시 정리

이번 구현에서의 목표는 명확했다.

  • 서버는 파일 데이터를 직접 받지 않는다
  • 프론트가 S3로 직접 업로드한다
  • 서버는 업로드를 허용하고, 파일 상태를 확정하는 역할만 한다

그래서 서버에 필요한 API는 딱 두 개였다.

  1. 임시 업로드용 presigned URL 발급 API
  2. 파일 확정(confirm) API

1. 임시 업로드용 API

역할

  • 프론트가 PDF 파일을 업로드할 수 있도록
  • presigned URL과 tempKey를 발급해준다

이 API에서 서버가 하는 일은 단순하다.

  • UUID를 생성한다
  • temp/{uuid}.pdf 형태의 key를 만든다
  • 해당 key에 대한 presigned URL을 발급한다

이 단계에서는:

  • DB 접근 ❌
  • 파일 처리 ❌
  • 비즈니스 로직 ❌

오직 "업로드를 허가해주는 역할”만 한다.


2. 프론트에서의 업로드

프론트는:

  1. 업로드 버튼 클릭
  2. 서버에서 받은 presigned URL로
  3. PDF 파일을 S3에 직접 업로드

이때 파일은:

temp/{uuid}.pdf

 

경로에 저장되고, 아직 어떤 publication과도 연결되지 않은 임시 상태다.


3. 파일 확정(confirm) API

publication 생성이 끝난 뒤, 파일을 확정하기 위해 호출되는 API다.

이 API의 책임

  • 임시 파일을 확정 경로로 이동
  • DB에는 관여하지 않음

입력값은 단순하다.

  • tempKey
  • publicationId

서버는 이 요청을 받으면:

  1. tempKey가 유효한지 확인하고
  2. paper/{publicationId}.pdf 경로를 생성한 뒤
  3. S3에서 copy → delete로 파일을 이동한다
  4. 최종 key(finalKey)를 반환한다

이렇게 하면:

  • DB에는 항상 확정된 파일 경로만 저장된다
  • temp 파일이 그대로 남는 상황을 피할 수 있다

IAM Role 기반 인증

S3 접근을 위해
access key를 코드에 넣지는 않았다.

EC2에 IAM Role을 연결하고,
서버에서는 AWS SDK가 해당 Role을 자동으로 사용하도록 했다.

덕분에:

  • 키 노출 위험이 없고
  • 환경별 설정도 단순해졌다

temp 파일 정리 전략

임시 업로드 파일은
publication으로 확정되지 않으면 결국 필요 없는 파일이다.

그래서 S3에 Lifecycle Rule을 추가했다.

  • temp/ prefix
  • 3일 후 자동 삭제

이 설정 하나로:

  • 업로드만 하고 취소된 파일
  • confirm이 호출되지 않은 파일

을 자동으로 정리할 수 있었다.


전체 흐름 다시 한 번 정리

1. 프론트 → 서버 임시 업로드 URL 요청
2. 프론트 → S3 PDF 파일 임시 업로드
3. 프론트 → publication API tempKey 전달
4.publication 처리 완료 → 파일 확정 API 호출
5. 서버 temp → paper 경로로 이동

서버는 끝까지:

  • 파일 내용을 직접 다루지 않고
  • 파일의 상태만 관리한다

구현하면서 느낀 점

이 구조의 가장 큰 장점은
책임이 명확해진다는 점이었다.

  • 파일 업로드/이동: 파일 담당
  • PDF 파싱/DB 저장: publication 담당

서로의 영역을 침범하지 않으니
기능 변경이나 확장도 훨씬 편해졌다.


마무리

이번 시리즈에서는
단순히 “S3 업로드 구현”이 아니라,

  • 왜 기존 구조가 문제였는지
  • 어떤 기준으로 설계를 바꿨는지
  • 그 설계를 어떻게 최소한으로 구현했는지

를 정리해보려고 했다.

비슷한 상황에서
파일 업로드 구조를 고민하고 있다면,
이 방식이 하나의 선택지가 되었으면 한다.