💻 프로젝트/트러블 슈팅

[QRoad]PDF 기반 publication 업로드 구조 개선기 – 2편: S3 presigned URL 설계

SoloQuest 2026. 2. 11. 11:48

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

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

 

1편에서는 기존 텍스트 기반 publication 저장 구조가
왜 PDF 업로드 방식과 맞지 않았는지를 정리했다.

이번 글에서는 그 고민의 연장선에서
“서버가 파일을 직접 받지 않는 업로드 구조”를 어떻게 설계했는지,
그리고 왜 S3 presigned URL을 선택했는지를 정리해보려고 한다.


서버가 파일을 직접 받으면 생기는 문제

가장 단순한 파일 업로드 구조는 보통 이렇다.

 
프론트 → 서버 → S3

서버가 multipart 요청으로 파일을 받고,
그 파일을 다시 S3에 업로드하는 방식이다.

처음엔 익숙하고 구현도 쉬워 보이지만,
실제로는 여러 문제가 숨어 있었다.

  • 서버가 파일 데이터를 직접 처리해야 하고
  • 파일 크기가 커질수록 메모리/디스크 부담이 커지며
  • 업로드 도중 서버가 죽으면 전체 요청이 실패한다

특히 publication 생성처럼
파일 업로드 이후 추가 작업이 이어지는 흐름에서는
서버가 병목이 되기 쉽다.


“파일 업로드”와 “비즈니스 로직”은 성격이 다르다

여기서 한 가지를 분리해서 볼 필요가 있었다.

  • 파일 업로드: 대용량 I/O 작업
  • publication 생성: 비즈니스 로직

이 둘을 같은 API에서 처리하면:

  • 실패 지점이 불분명해지고
  • 예외 처리가 복잡해지며
  • 역할 경계도 흐려진다

그래서 목표를 이렇게 잡았다.

“서버는 파일을 저장하지 말고,
파일을 다루는 ‘흐름’만 관리하자.”


presigned URL이 해결해준 것

S3 presigned URL은
서버가 가진 S3 접근 권한을,
아주 제한된 형태로 잠시 빌려주는 URL
이다.

이 방식을 사용하면 업로드 흐름이 바뀐다.

 
프론트 → S3 (직접 업로드) 프론트 → 서버 (메타데이터 전달)

서버는:

  • 파일 데이터를 직접 받지 않고
  • “어디에 업로드할지”만 결정한다

이 구조가 마음에 들었던 이유는 명확했다.


1. 서버 부담이 거의 없다

파일 데이터는 프론트에서 S3로 바로 전송된다.
서버는 업로드 요청을 처리하지 않기 때문에

  • 메모리/디스크 부담이 없고
  • 트래픽 증가에도 비교적 안정적이다

2. 업로드와 비즈니스 로직을 분리할 수 있다

파일 업로드는 사전 작업,
publication 생성은 확정 작업으로 분리할 수 있다.

이 덕분에:

  • 파일만 다시 올리는 것도 가능하고
  • publication 생성 실패 시에도
    파일을 바로 버릴 필요가 없다

3. 보안도 충분히 통제할 수 있다

presigned URL은:

  • 특정 객체(key)에만 접근 가능하고
  • PUT 같은 특정 동작만 허용되며
  • 짧은 시간 후 자동으로 만료된다

버킷을 public으로 열 필요도 없고,
프론트에 AWS 키를 노출할 필요도 없다.


임시(temp) 경로와 확정(final) 경로

설계를 하면서 한 가지 규칙을 더 추가했다.

“업로드된 파일은 바로 확정하지 않는다.”

 

그래서 S3 경로를 두 단계로 나눴다.

 
temp/{uuid}.pdf     // 임시 업로드
paper/{id}.pdf      // publication 확정 파일
  • temp/ 경로의 파일은 언제든 사라질 수 있고
  • publication 생성이 끝난 뒤에만
    paper/ 경로로 이동한다

이렇게 하면:

  • 업로드만 하고 취소된 파일은 정리할 수 있고
  • DB에는 확정된 파일만 남길 수 있다

전체 흐름 정리

지금까지 정리한 구조를 한 번에 보면 이렇다.

1. 프론트 → 서버 임시 업로드용 presigned URL 요청
2. 프론트 → S3 PDF 파일 임시 업로드 (temp)
3. 프론트 → publication API tempKey 전달
4.publication 처리 완료 후 파일 확정 요청 → temp → final 이동

이 흐름에서 서버는

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