Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Karsei/spring-convention-sample

Repository files navigation

spring-convention

사내에서 컨벤션 적용을 위해 제작했던 Spring 용 라이브러리 샘플입니다.

  • demo - 시연용
  • spring-convention - spring boot 2 버전용
  • spring-convention-jakarta - spring boot 3 버전용
  • core - 컨벤션에 필요한 공통 클래스 연관

사용법

해당 라이브러리를 clone 하여 demo 모듈에서 직접 시험해볼 수 있습니다.

애플리케이션을 실행한 후, http://localhost/swagger-ui/index.html 으로 접근하여 테스트를 해볼 수 있습니다.

application.properties(또는 application.yml) 파일을 수정합니다.

# 특수문자 허용. 반드시 추가
server.tomcat.relaxed-query-chars="[,]"

아래는 지원하는 property 목록이며 활성화하거나 비활성화가 가능합니다.

# QueryString filter 형식, snake_case 파라미터 지원 적용
convention.rest.enabled=true
# Swagger 변환 지원 적용
convention.swagger.enabled=true

GroupedOpenApi 를 사용하고 있을 경우

어느 애플리케이션에서는 GroupedOpenApi 를 Bean 으로 등록하여 API를 그룹별로 관리하고 있을 수 있습니다. 이 경우에 Pageable 관련 파라미터가 Swagger 문서에 자동으로 컨벤션 형식에 맞게 적용이 되지 않을 수 있습니다. 그럴 경우에는 아래처럼 수동으로 .addOperationCustomizer() 를 추가하여 직접 지정해주어야 합니다.

@Bean
public GroupedOpenApi someApi(SpringDataWebProperties webProperties) {
 return GroupedOpenApi.builder()
 .group("Api")
 .pathsToMatch("/v1/**")
 // 아래 추가
 .addOperationCustomizer(new SwaggerCustomizer.SwaggerOperationCustomizer(webProperties))
 .build();
}

특수문자가 들어간 경우 Escape 처리하여 실행하면 됩니다.

특징

응답 포맷 지원

주로 사용될 만한 3가지 형식의 기본 클래스를 사용할 수 있습니다.

  • EntryApiResponse - 단일 데이터 응답
  • CollectApiResponse - 복수 데이터 응답
  • PageableApiResponse - 페이징 복수 데이터 응답

아래 2개의 인터페이스를 지원합니다.

  • ApiResponse
  • AdditionalApiResponse
@GetMapping
@ResponseStatus(HttpStatus.OK)
public EntryApiResponse<SomeResult> findItem(Long id) {
 EntryApiResponse result = useCase.find(id);
 return EntryApiResponse.of(result);
}
@GetMapping
@ResponseStatus(HttpStatus.OK)
public CollectApiResponse<SomeResult> findItems(SomeRequest request) {
 List<SomeResult> results = useCase.find(request);
 return CollectApiResponse.of(results);
}
@GetMapping
@ResponseStatus(HttpStatus.OK)
public PageableApiResponse<SomeResult> findItems(SomeRequest request,
 Pageable pageable) {
 Page<SomeResult> results = useCase.find(request, pageable);
 return PageableApiResponse.of(results);
}

오류 포맷 지원

주로 사용될 만한 2가지 형식의 기본 클래스를 사용할 수 있습니다.

  • MandatoryErrorApiResponse - 오류 코드, 메시지만 제공
  • DetailErrorApiResponse - 오류 코드, 메시지, 상세 제공

아래 1개의 인터페이스를 지원합니다.

  • ErrorApiResponse

filter 형식 지원

  • filter[domain]=google.com
  • filter[user_id][like]=leejy
  • page[offset]=2
  • page[limit]=5
  • sort[some_field]=asc
  • sort[0][some_field]=asc

http://localhost?filter[domain]=google.com&filter[user_id][like]=leejy&page[offset]=2&page[limit]=5

위와 같은 QueryString filter 형식을 지원합니다.

Swagger @ParameterObject filter 형식 지원

Controller 단에서 @ModelAttribute 로 사용되는 클래스가 있다면 Swagger 에서 제공하는 @ParameterObject 를 통해 Swagger 문서를 간편하게 작성할 수 있습니다.

Swagger 문서 작성 시 @ConventionFilter를 붙여서 filter 형식으로 작성할 수 있습니다.

  • 요청 클래스 상단에 @ConventionFilter 를 붙여야 합니다.
    • 반드시 필드 이름 맨 뒤에는 Operator 를 CamelCase 로 붙여야 합니다. 예를 들어, userIdlike Operator 를 적용하고 싶을 경우, userIdLike 라고 붙여야 합니다.
    • 예시
      • userIdEq -> filter[user_id][eq]
      • userIdLike -> filter[user_id][like]
      • userIdIn -> filter[user_id][in]
@Getter
@Setter
@ConventionFilter
public class SomeRequest {
 @Parameter(description = "유저 아이디")
 private String userIdEq;
 @Parameter(description = "유저 아이디 (LIKE)")
 private String userIdLike;
 @Parameter(description = "만기일 (Start)")
 private LocalDate expireDateGte;
 @Parameter(description = "만기일 (End)")
 private LocalDate expireDateLt;
 @Parameter(description = "주문번호")
 private String orderNumEq;
}
  • Pageable 이 컨벤션 형식으로 출력되려면 Controller 단에서 파라미터 Pageable@ConventionFilter 를 붙여야 합니다.
    • sort 는 변환되지 않습니다. 단, 요청을 받을 때는 지원합니다.
    • 예시
      • page -> page[offset]
      • size -> page[limit]
@GetMapping
@ResponseStatus(HttpStatus.OK)
public PageableApiResponse<SomeResult> findItems(@ParameterObject SomeRequest request, 
 @ParameterObject @ConventionFilter Pageable pageable)

Swagger 예시

기타

요청, 응답 Payload JSON 관련

해당 라이브러리를 사용했을 때 강제로 요청, 응답 클래스를 snake_case 로 자동으로 변환하지는 않습니다.

응답 클래스들을 snake_case 로 출력되도록 할 경우 application.properties(또는 application.yml) 파일에서 아래와 같이 설정하면 전역으로 적용됩니다.

spring.jackson.property-naming-strategy=SNAKE_CASE

단, 기존 애플리케이션에 작성된 API 들의 호환성을 고려해야 할 경우에는 아래처럼 각 클래스 상단에 @JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class) 를 붙여서 사용합니다.

@Getter
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
public class SomeDto {
 @Schema(description = "유저 아이디", example = "leejy")
 private String userId;
 @Schema(description = "테스트")
 private String blah;
}

최대 페이지 사이즈

Spring Web 에서는 최대 페이지 사이즈를 지정하도록 property 를 자체적으로 제공하고 있습니다. 최대 페이지 사이즈를 넘어선 요청이 들어올 경우, 설정에서 지정된 최대 사이즈로 고정됩니다.

전역으로 적용할 경우 아래와 같이 설정할 수 있습니다.

# 최대 페이지 사이즈 지정 (기본값: 2000)
spring.data.web.pageable.max-page-size=2000

전역이 아닌 일부 요청에만 적용하고 싶을 경우 @LimitedPageSize 를 파라미터에 작성하여 아래와 같이 설정하고 이용할 수 있습니다.

public PageableApiResponse<TestDto> paginationMaxSizeTest(
 @ParameterObject @PageableDefault(size = 15) @LimitedPageSize(maxSize = 1000) Pageable pageable) {

위에 작성된 모든 사항은 필터 형식(page[limit])도 지원됩니다.

About

컨벤션 라이브러리 샘플

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

AltStyle によって変換されたページ (->オリジナル) /