서버 운영
관리자 업로드 API에 presigned URL을 붙일지 서버 프록시를 둘지 비교한 기준
이미지 업로드 경로를 설계할 때 presigned URL과 서버 프록시의 장단점을 권한, 용량, 관측성 기준으로 비교합니다.
업로드가 느린 이유를 API부터 봤다
관리자에서 12MB 이미지를 올릴 때 저장 버튼이 멈췄다. 브라우저 요청을 보니 파일이 앱 서버를 거쳐 스토리지로 한 번 더 이동했다. 작은 인스턴스에서는 메모리와 대역폭을 동시에 쓰는 경로였다.
책임으로 비교했다
| 기준 | 서버 프록시 | presigned URL |
|---|---|---|
| 파일 경로 | 브라우저 → 앱 서버 → 스토리지 | 브라우저 → 스토리지 |
| 내용 검사 | 서버에서 즉시 가능 | URL 발급 전 정책 검사 |
| 앱 서버 부하 | 파일 크기만큼 증가 | 거의 없음 |
변환이나 바이러스 검사가 꼭 필요하면 프록시가 단순하다. 이미지를 그대로 보관하는 관리자 화면은 presigned URL을 선택했고, 발급 API에서 권한과 타입을 제한했다.
if (!session.user.isAdmin) {
return Response.json({ message: 'forbidden' }, { status: 403 });
}
if (!['image/jpeg', 'image/png', 'image/webp'].includes(input.contentType)) {
return Response.json({ message: 'unsupported type' }, { status: 400 });
}
const key = `uploads/${crypto.randomUUID()}`;
원래 파일명은 객체 키로 쓰지 않았다. 경로 조작과 이름 충돌을 피하려는 선택이다. 업로드가 끝났다는 클라이언트 신호도 그대로 믿지 않고, 서버가 객체 크기와 content type을 다시 확인한 뒤 글에 연결했다.
다음 테스트 목록
- 만료된 URL로 업로드가 거절되는가
- 다른 관리자의 key를 연결할 수 없는가
- 0바이트 파일과 허용하지 않은 타입이 막히는가
큰 파일이라서가 아니라 앱 서버가 파일 내용을 실제로 처리해야 하는지를 기준으로 결정했다.