Springboot Controller 에서 Request Body/Parameter 와 많은 Response, GET 요청의 필터들까지 포함하여 OpenAPI 를 작성하다보면 OpenAPI Annocation 의 라인수가 상당히 길어져 가독성이 떨어지고 화면이 넘어가 관리하기 힘든 상황이 발생한다.
Controller 소스에서 API 기능과 OpenAPI 문서를 분리하여 가독성을 높이고 관리하기 용이하게 변경해보자.
AS-IS
우선, 기존의 Controller 가 아래와 비슷한 형태일 것이다.
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/v1/comment/like")
public class BookmarkAddController {
private final BookmarkAddService bookmarkAddService;
@PostMapping
@Operation(
summary = "북마크 추가 API",
description = """
사용자가 게시물에 북마크를 합니다.
- 사용자는 MemberEntity 의 id 로 BookmarkEntity 의 memberId 와 ID Reference 관계입니다.
"""
)
@ApiResponses(value = {
@ApiResponse(
responseCode = "200",
description = """
북마크 처리 성공
- 처리 성공 시나리오를 반환함.
- 북마크가 된 경우 EnvelopeResponse 의 Data 에 isExists 값이 true 로 반환
- 이미 북마크가 되어있는 경우 EnvelopeResponse 의 Data 에 isExists 값이 false 로 반환
""",
content = @Content(
schema = @Schema(implementation = BookmarkAddResponse.class)
)
),
@ApiResponse(
responseCode = "401",
description = "인증 실패",
content = @Content(schema = @Schema(implementation = Error.class)) // 공통 에러 객체 연결 가능
),
@ApiResponse(
responseCode = "404",
description = "게시물이 존재하지 않음"
)
})
public ResponseEntity<BookmarkAddResponse> addBookmark(
@RequestBody BookmarkAddRequest request
) {
BookmarkAddResDto resDto = bookmarkAddService.addBookmark(request.toDto());
return ResponseEntity
.status(resDto.result().isExists() ? HttpStatus.CREATED : HttpStatus.OK)
.body(BookmarkAddResponse.from(resDto));
}
}
실제 Controller 의 소스는 8 라인밖에 없지만 해당 Controller 소스파일의 반이상이 OpenAPI 문서작성으로 차지하고 있다.
해당 예제소스가 Toggle Action 형태의 Bookmark 예제 라서 이 정도로 끝나지만, Member, Board 도메인의 Controller 를 제대로 만들어 Request Body, Pageable, Response 등을 OpenAPI에 제대로 작성하다보면 계속 스크롤을 위아래로 흔들고 있을것이다.
마우스 스크롤도 딸깍 하지않고 오래 긁어야해서 상당히 피곤해진다.
TO-BE
@Operation 과 @ApiResponses 등의 OpenAPI 어노테이션을 분리해서 Controller 에서 등록만하도록 변경해보자.
아래와 같이 Controller 함수에 대응되는 Custom Annotation 을 만든다.
Operation Annotion 를 위한 Controller 함수와 1대1 대응되게 분리한다.
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Operation(
summary = "북마크 추가 API",
description = """
사용자가 게시물에 북마크를 합니다.
- 사용자는 MemberEntity 의 id 로 BookmarkEntity 의 memberId 와 ID Reference 관계입니다.
"""
)
@ApiResponses(value = {
@ApiResponse(
responseCode = "200",
description = """
북마크 처리 성공
- 처리 성공 시나리오를 반환함.
- 북마크가 된 경우 EnvelopeResponse 의 Data 에 isExists 값이 true 로 반환
- 이미 북마크가 되어있는 경우 EnvelopeResponse 의 Data 에 isExists 값이 false 로 반환
""",
content = @Content(
schema = @Schema(implementation = BookmarkAddResponse.class)
)
),
@ApiResponse(
responseCode = "401",
description = "인증 실패",
content = @Content(schema = @Schema(implementation = Error.class)) // 공통 에러 객체 연결 가능
),
@ApiResponse(
responseCode = "404",
description = "게시물이 존재하지 않음"
)
})
public @interface BookmarkAddOperation {
}
아래와 같이 생성한 OpenAPI 용 Custom Annotation 인 @BookmarkAddOperation 을 추가하여 Controller 코드에서는 RestAPI 에 집중하도록 한다.
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/v1/comment/like")
public class BookmarkAddController {
private final BookmarkAddService bookmarkAddService;
@PostMapping
@BookmarkAddOperation
public ResponseEntity<BookmarkAddResponse> addBookmark(
@RequestBody BookmarkAddRequest request
) {
BookmarkAddResDto resDto = bookmarkAddService.addBookmark(request.toDto());
return ResponseEntity
.status(resDto.result().isExists() ? HttpStatus.CREATED : HttpStatus.OK)
.body(BookmarkAddResponse.from(resDto));
}
}
'개발 > spingboot' 카테고리의 다른 글
| Springboot 설정(application.yaml) 우선순위 (0) | 2026.02.19 |
|---|---|
| H2 Datasource 설정 - File Based 방식 (0) | 2026.02.19 |