diff --git a/src/main/kotlin/com/ixfp/gitmon/config/web/WebMvcConfig.kt b/src/main/kotlin/com/ixfp/gitmon/config/web/WebMvcConfig.kt index b0e2787..47c8f92 100644 --- a/src/main/kotlin/com/ixfp/gitmon/config/web/WebMvcConfig.kt +++ b/src/main/kotlin/com/ixfp/gitmon/config/web/WebMvcConfig.kt @@ -14,6 +14,7 @@ class WebMvcConfig( .addPathPatterns("/api/v1/member/repo/**") // 인증이 필요한 경로 .addPathPatterns("/api/v1/member", "/api/v1/member/") .addPathPatterns("/api/v1/posting", "/api/v1/posting/") + .addPathPatterns("/api/v1/posting/images", "/api/v1/posting/images/") } override fun addCorsMappings(registry: CorsRegistry) { diff --git a/src/main/kotlin/com/ixfp/gitmon/controller/IPostingController.kt b/src/main/kotlin/com/ixfp/gitmon/controller/IPostingController.kt index 68a3d6f..4fe1c44 100644 --- a/src/main/kotlin/com/ixfp/gitmon/controller/IPostingController.kt +++ b/src/main/kotlin/com/ixfp/gitmon/controller/IPostingController.kt @@ -110,4 +110,81 @@ interface IPostingController { content: MultipartFile, member: Member, ): ResponseEntity> + + @Operation( + summary = "이미지 업로드", + description = "포스팅에 사용할 이미지를 업로드합니다.", + security = [SecurityRequirement(name = ACCESS_TOKEN)], + ) + @ApiResponses( + value = [ + ApiResponse( + responseCode = "201", + description = "이미지 업로드 성공", + content = [ + Content( + mediaType = "application/json", + schema = + Schema( + example = """ + { + "status": "CREATED", + "data": "https://raw.githubusercontent.com/user/repo/main/images/uuid.jpg" + } + """, + ), + ), + ], + ), + ApiResponse( + responseCode = "400", + description = "허용되지 않은 이미지 확장자", + content = [ + Content( + mediaType = "application/json", + schema = + Schema( + example = """ + { + "status": "BAD_REQUEST", + "errorMessage": "invalid image extension" + } + """, + ), + ), + ], + ), + ApiResponse( + responseCode = "409", + description = "사용자의 레포지토리가 아직 설정되지 않음", + content = [ + Content( + mediaType = "application/json", + schema = + Schema( + example = """ + { + "status": "CONFLICT", + "errorMessage": "repository not configured" + } + """, + ), + ), + ], + ), + ], + ) + @io.swagger.v3.oas.annotations.parameters.RequestBody( + description = "업로드할 이미지 파일", + required = true, + content = [ + Content( + mediaType = MediaType.MULTIPART_FORM_DATA_VALUE, + ), + ], + ) + fun uploadImage( + image: MultipartFile, + member: Member, + ): ResponseEntity> } diff --git a/src/main/kotlin/com/ixfp/gitmon/controller/PostingController.kt b/src/main/kotlin/com/ixfp/gitmon/controller/PostingController.kt index 98d76c7..08a1923 100644 --- a/src/main/kotlin/com/ixfp/gitmon/controller/PostingController.kt +++ b/src/main/kotlin/com/ixfp/gitmon/controller/PostingController.kt @@ -77,6 +77,18 @@ class PostingController( return ApiResponseHelper.success(posting) } + @PostMapping( + "/images", + consumes = [MediaType.MULTIPART_FORM_DATA_VALUE], + ) + override fun uploadImage( + @RequestPart image: MultipartFile, + @RequestAttribute(AUTHENTICATED_MEMBER) member: Member, + ): ResponseEntity> { + val imageUrl = postingService.uploadImage(member, image) + return ApiResponseHelper.created(imageUrl) + } + companion object { private val log = logger {} } diff --git a/src/main/kotlin/com/ixfp/gitmon/domain/posting/PostingService.kt b/src/main/kotlin/com/ixfp/gitmon/domain/posting/PostingService.kt index 88523da..7db461c 100644 --- a/src/main/kotlin/com/ixfp/gitmon/domain/posting/PostingService.kt +++ b/src/main/kotlin/com/ixfp/gitmon/domain/posting/PostingService.kt @@ -140,7 +140,7 @@ class PostingService( return updatedPostingId } - private fun uploadImage( + fun uploadImage( member: Member, content: MultipartFile, ): String { diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml new file mode 100644 index 0000000..746eaf3 --- /dev/null +++ b/src/main/resources/application-dev.yml @@ -0,0 +1,5 @@ +oauth2: + client: + github: + id: ${GITHUB_OAUTH2_CLIENT_ID_DEV} + secret: ${GITHUB_OAUTH2_CLIENT_SECRET_DEV} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 51edf67..f02373a 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -1,6 +1,10 @@ spring: application: name: gitmon + servlet: + multipart: + max-file-size: 10MB + max-request-size: 10MB datasource: url: ${DATABASE_URL} username: ${DATABASE_USERNAME}