Swagger(스웨거)는 개발자가 REST API 서비스를 설계, 빌드, 문서화할 수 있도록 하는 프로젝트이다.
다른 개발팀과 협업을 진행하거나 이미 구축되어있는 프로젝트에 대한 유지보수를 진행할 경우그리고
백엔드의 API를 호출하는 프론트엔드 프로그램을 제작할 경우 유용하게 사용할수있다.
스웨거의 장점으로 적용하기 쉽고 api를 테스트할수 있는 화면을 제공한다.
단점으로는 어노테이션을 추가하는 방식으로 설정해야하는 단점이 있다.
이제 프로젝트에 스웨거를 적용해보자
1. 스웨거 의존성 추가
compile (group: 'io.springfox', name: 'springfox-swagger2', version: '2.9.2'){
exclude module: 'swagger-annotations' exclude module: 'swagger-models'
}
compile "io.swagger:swagger-annotations:1.5.21"
compile "io.swagger:swagger-models:1.5.21"
compile group: 'io.springfox', name: 'springfox-swagger-ui', version: '2.9.2'
2. 스웨거 설정 추가
import com.fasterxml.classmate.TypeResolver;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.domain.Pageable;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.schema.AlternateTypeRules;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.ApiKey;
import springfox.documentation.service.AuthorizationScope;
import springfox.documentation.service.SecurityReference;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import java.util.Collections;
import java.util.List;
@EnableSwagger2
@RequiredArgsConstructor
@Configuration
public class Swagger2Config {
private final TypeResolver typeResolver;
@Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.useDefaultResponseMessages(false)
.alternateTypeRules(AlternateTypeRules
.newRule(typeResolver.resolve(Pageable.class), typeResolver.resolve(Page.class)))
.apiInfo(apiInfo())
.securityContexts(Collections.singletonList(securityContext()))
.securitySchemes(Collections.singletonList(apiKey()))
.select()
.apis(RequestHandlerSelectors.basePackage("com.myintroduce.web.api"))
.paths(PathSelectors.ant("/api/**"))
.build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("MY-INTRODUCE REST 프로젝트 API DOC")
.version("v.1")
.description("자기소개 페이지 REST 프로젝트의 문서")
.termsOfServiceUrl("http://ec2-35-168-161-112.compute-1.amazonaws.com/")
.license("MY-INTRODUCE Licenses")
.licenseUrl("https://github.com/whdals7337/myintroduce-backend-project")
.build();
}
private ApiKey apiKey() {
return new ApiKey("JWT", "Authorization", "header");
}
private SecurityContext securityContext() {
return SecurityContext.builder().securityReferences(defaultAuth()).build();
}
private List<SecurityReference> defaultAuth() {
AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
authorizationScopes[0] = authorizationScope;
return Collections.singletonList(new SecurityReference("JWT", authorizationScopes));
}
@Getter @Setter
@ApiModel
static class Page {
@ApiModelProperty(value = "페이지 번호(0..N)")
private Integer page;
@ApiModelProperty(value = "페이지 크기", allowableValues="range[0, 100]")
private Integer size;
@ApiModelProperty(value = "정렬(사용법: 컬럼명,ASC|DESC)")
private List<String> sort;
}
}
위의 경우 전체 설정과 swagger ui로 나눠서 설명하도록하겠습니다.
api 정보 설정 부분
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("MY-INTRODUCE REST 프로젝트 API DOC")
.version("v.1")
.description("자기소개 페이지 REST 프로젝트의 문서")
.termsOfServiceUrl("http://ec2-35-168-161-112.compute-1.amazonaws.com/")
.license("MY-INTRODUCE Licenses")
.licenseUrl("https://github.com/whdals7337/myintroduce-backend-project")
.build();
}
license와 Terms of service의 경우 클릭시 설정한 url로 이동하게 된다.
2. Page 파라미터를 위한 Page class
Swagger가 Pageable를 제대로 잡히지 않기 때문에 새로 만들어서 설정하기 위해서 만들었다.
@Getter @Setter
@ApiModel
static class Page {
@ApiModelProperty(value = "페이지 번호(0..N)")
private Integer page;
@ApiModelProperty(value = "페이지 크기", allowableValues="range[0, 100]")
private Integer size;
@ApiModelProperty(value = "정렬(사용법: 컬럼명,ASC|DESC)")
private List<String> sort;
}
3. Spring Security 설정
자기소개 페이지가 jwt를 통해서 인증, 인가를 설정해놨기 때문에 swagger에도 해당 설정을 잡아준 부분이다.
private ApiKey apiKey() {
return new ApiKey("JWT", "Authorization", "header");
}
private SecurityContext securityContext() {
return SecurityContext.builder().securityReferences(defaultAuth()).build();
}
private List<SecurityReference> defaultAuth() {
AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
authorizationScopes[0] = authorizationScope;
return Collections.singletonList(new SecurityReference("JWT", authorizationScopes));
}
4. swagger 문서 api 설정
@Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.useDefaultResponseMessages(false)
.alternateTypeRules(AlternateTypeRules
.newRule(typeResolver.resolve(Pageable.class), typeResolver.resolve(Page.class)))
.apiInfo(apiInfo())
.securityContexts(Collections.singletonList(securityContext()))
.securitySchemes(Collections.singletonList(apiKey()))
.select()
.apis(RequestHandlerSelectors.basePackage("com.myintroduce.web.api"))
.paths(PathSelectors.ant("/api/**"))
.build();
}
useDefaultResponseMessages: 기본 응답 메세지 설정
alternateTypeRule: Pageable 클래스를 Page 클래스로 타입을 대체하도록 규칙 설정
apiInfo: 앞서 설정한 api 정보를 셋팅
apis(RequestHandlerSelectors.basePackage("com.myintroduce.web.api")) : swagger를 적용할 패키지 설정
path: swagger를 적용할 주소 패턴을 셋팅
파라미터 관련 설정
value : 설명
required : 파라미터의 필수 여부
exampel : 기본값 설정
spring security를 사용하는 경우
해당 버튼 클릭시
본인이 적용한 방식의 인증을 요구합니다. 위 사진의 경우 jwt 토큰 값을 요구하는 것으로 인증, 인가가 필요한 요청을 할경우 인증후 테스트가 가능합니다.
github.com/whdals7337/myintroduce-backend-project
'자기소개페이지만들기' 카테고리의 다른 글
6. scouter를 통해서 백엔드 모니터링 해보기 (2) | 2021.02.24 |
---|---|
5. 자기소개 백엔드에 nGrinder로 부하 발생시켜 보기 (0) | 2021.02.24 |
3. nginx로 로드 밸런싱 하기 (0) | 2021.02.15 |
2. 자기소개 페이지 백엔드, 프론트엔트 분리하기 (0) | 2021.02.15 |
1. 자기소개 페이지 내용 (0) | 2021.02.01 |