-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
MultipartFile 요청 명세 수정 완료 #453
Conversation
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
아마 @SongJaeHoonn 님께서도 해당 docs를 살펴보신 것 같습니다. 저도 MultipartFile을 전달할 때 @RequestPart
와 @RequestParam
사이에서 고민한 적은 있어도 @RequestBody
를 사용할 경우 장점을 잘 모르겠습니다.
오히려 아래와 같은 상황이 우려됩니다.
복잡성 증가
파일 데이터를 JSON 형식으로 인코딩해야 하므로 클라이언트와 서버 모두에서 추가적인 인코딩 및 디코딩 작업이 필요해보입니다.
성능 저하
파일 데이터를 Base64 등으로 인코딩하면 데이터 크기가 커져 네트워크 대역폭과 메모리 사용량이 증가할 것으로 예상됩니다.
파일 크기 제한
JSON으로 인코딩된 파일은 크기가 커질 수 있고, 경우에 따라 HTTP 요청의 크기 제한 때문에 문제가 생길 수 있을 것 같습니다.
@RequestBody
의 사용 필요성을 조금 더 설명해주시면 이해하는데 더 도움이 될 것 같습니다!
처음 작업하게 된 계기는
해당 라이브러리 메인테이너는 또한 작업을 진행하기 전에 프론트 팀에게 문의한 결과, 이미 데이터를 @SongJaeHoonn 님과 @mingmingmon 님께서 언급하신 부분 또한 찾아보았습니다. 공식 문서와 다양한 자료를 참고해봤을 때, 일반적으로 자세히 알아보지 않고 성급히 작업한 점에 대해 죄송하게 생각합니다. |
@limehee @SongJaeHoonn @mingmingmon 해당 이슈와 관련하여 논의가 필요할 거 같아 의견을 남겨요. 프론트엔드팀에서는 API 문서와 테스트 도구를 Swagger를 사용하고 있어요. 댓글 살펴봤을 때 |
팀원들의 의견도 들어봐야겠지만, 해당 이슈와 관련하여 메인테이너에게 문의를 남겨둔 상태입니다. 상황을 좀 더 지켜봐야 할 것 같습니다. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Swagger 버전 차이로 인한 문제였군요.
@RequestParam
을 사용할 경우 Swagger를 통한 파일 업로드 테스트가 불가능하다면, @RequestBody
를 사용해야 될 것 같습니다.
다만 제가 List<MultipartFile>
과 @RequestPart
, 단일 MultipartFile
와 @RequestPart
을 조합해서 테스트 해보니, 아래와 같은 결과가 나왔습니다. 결론적으로 List<MultipartFile>
의 전달을 @RequestPart
로 하는 것을 제안합니다.
실행환경
org.springdoc:springdoc-openapi-starter-webmvc-ui:2.6.0
'org.springframework.boot' version '3.3.2'
실행결과
List<MultipartFile>
와@RequestPart
인 경우 ->@RequestBody
로List<MultipartFile>
이 전달되면서 정상 작동
- 단일
MultipartFile
와@RequestParam
인 경우 ->@RequestBody
로MultipartFile
이 전달되면서 정상작동
이전에 저와 @SongJaeHoonn 님이 주장했던 것에 따르면 MultipartFile
은 @RequestParam
와 @RequestPart
로 전달이 가능한 것이고, @RequestBody
로 전달하는 것 보다 표준화 되고 추천되는 방법이라고 했습니다.
해당 이슈를 해결하기 위해서 @RequestParam
, @RequestPart
, @ReqeustBody
의 차이점을 더 알아본 결과 아래와 같이 정리 할 수 있었습니다.
(참고 자료 : https://velog.io/@hwan2da/Spring-RequestBody-vs-RequestParam-vs-RequestPart-vs-ModelAttribute, https://somuchthings.tistory.com/160)
@RequestBody
- XML과 JSON을 전달하는데 사용됩니다. 코드 상에서
consumes = MediaType.MULTIPART_FORM_DATA_VALUE
를 명시하지 않으면@RequestBody
로는 원래MultipartFile
을 전달할 수 없습니다. 아래에 실행 사진 첨부합니다.
@RequestParam
- 메소드 파라미터 타입이 String 또는
MultipartFile/Part
가 아닌 경우Converter
또는PropertyEditor
를 참조해 변환을 시도하는 점이@RequestPart
와 차이가 있습니다.MultipartFile
의 경우는MultipartResolver
를 통해 변환이 된다고 합니다.
예상하건데, 따라서 Swagger 상에서 단일 MultipartFile
은 @RequestParam
으로 전달이 가능하게 된 것은 단일 MultipartFile
은 Converter
나 PropertyEditor
를 참조하지 않고 정상적으로 MultipartResolver
를 통한 변환이 이루어진 것으로 보입니다.
다만 Swagger측의 버그인지, List<MultipartFile>
을 전달할 경우는 오류가 나는 것을 보니, MultipartResolver
를 통한 변환이 안 되는 것 같습니다.
@RequestPart
- 메소드 파라미터 타입이 String 또는
MultipartFile/Part
가 아닌 경우 요청 헤더의 Content-Type을 참조하여 해당하는HttpMessageConveter
로 변환을 시도합니다. 마찬가지로MultipartFile
의 경우는MultipartResolver
를 통해 변환을 합니다. - 또한
@RequestPart
는MultipartFile
요청의 특정 파트만을 추출하여 처리합니다. 이 파트는request body
의 일부로 들어오지만,MultipartFile
구조에서 구분된 여러 파트 중 하나를 지정할 수 있습니다. 이 특징 때문에@RequestPart
를 사용했을 때 Swagger에서@RequestBody
로 파일이 전달됨을 확인할 수 있었습니다.
예상하건데, Swagger상에서 List<MultipartFile>
을 @RequestPart
로는 잘 변환하는 것을 보면 @RequestParam
은 단순히 폼 필드나 쿼리 파라미터, 혹은 파일 데이터를 처리할 때 주로 사용하는 것이고, @RequestPart
는 multipart/form-data의 특정 파트를 처리하며, 파일과 함께 JSON 또는 XML 데이터 등 복합 데이터 구조를 다룰 때 사용되는 특징에 의해서 Swagger에서 MultipartFile
의 전달을 @RequestPart
로 유도하고자 한 것이 아닌가 싶습니다.
마무리
@RequestBody
에 consumes = MediaType.MULTIPART_FORM_DATA_VALUE
명시하였을 때 List<MultipartFile>
이 전달이 되는 것과 @RequestPart
에 consumes = MediaType.MULTIPART_FORM_DATA_VALUE
를 명시하고 List<MultipartFile>
이 전달이 되는 것은 같은 결과가 나타나지만,
@RequestPart
가 MultipartFile
을 JSON이나 XML로 표현된 requestBody
의 요소들과 함께 전달하여도 MultipartFile
요청의 특정 파트만을 추출하여 처리하는 점과 request body
의 일부로 들어오지만, MultipartFile
구조에서 구분된 여러 파트 중 하나를 지정하는 특징 때문에
@RequestBody
보다 @RequetPart
를 사용하는 것이 더 알맞을 것 같습니다.
@limehee 께서 메인테이너에게 남긴 문의를 통해 해당 이슈가 고쳐질지 기다려 본 후, 만약 해결하기 어렵다면 @mingmingmon 께서 답변주신 |
@mingmingmon 민주님 분석 멋집니다..! 해당 내용을 코어팀 블로그에 글 작성해 보는 것은 어떨까요 |
@limehee 해당 PR은 일단 닫고 후에, Swagger 측에서 해당 이슈가 마무리 되면 다시 부탁드립니다~ |
Summary
현재 MultipartFile의 경우
@RequestParam
으로 데이터를 전달받고 있으나, 이는 잘못된 방식입니다.@RequestBody
를 사용하여 데이터를 올바르게 전달받을 수 있도록 수정합니다.Tasks
@RequestParam
어노테이션을@RequestBody
로 변경