Swagger
SpringBoot Swagger2
Swagger란
Swagger란 API 문서를 자동으로 만들어주는 라이브러리 입니다.
Swagger 구현
Gradle
//springfox-swagger2
compile group: 'io.springfox', name: 'springfox-swagger2', version: '2.9.2'
//springfox-swagger-ui
compile group: 'io.springfox', name: 'spxringfox-swagger-ui', version: '2.9.2'
Maven
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
SwaggerConfig.java
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("worker_api_v1")
.select()
.apis(RequestHandlerSelectors.any()) // 모든요청
.paths(PathSelectors.any()) //모든경로
.build().apiInfo(apiInfo());
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder().title("스웨거 Api")
.description("스웨거 튜토리얼! API!.")
.contact(new Contact("민동현", "https://daeakin.github.io/", "mindh890@gmail.com"))
.version("1.0.0")
.build();
}
}
웹에서 스웨거 접속하기.
http://localhost:{port}/swagger-ui.html
기본적으로 SpringBoot에 의해 만들어지는 컨트롤러들만 현재 노출되어있습니다.
apiInfo() 함수에 관한 내용들
private ApiInfo apiInfo() {
return new ApiInfoBuilder().title("스웨거 Api")
.description("스웨거 튜토리얼! API!.")
.contact(new Contact("민동현", "https://daeakin.github.io/", "mindh890@gmail.com"))
.version("1.0.0")
.build();
}
문서 작성용 컨트롤러 만들기.
테스트용 RestController 만들기
2개의 클래스를 더 만들어 보겠습니다.
TestController.java
@RestController
public class TestController {
@GetMapping("/test")
public TestDto testGetMethod(@RequestBody TestDto testDto) {
return new TestDto("Test!!",true);
}
}
TestDto.java
‼️ Swagger 문서화를 위해서는 Getter 메소드가 필요합니다.
public class TestDto {
private String message;
private boolean flag;
public TestDto(String message, boolean flag) {
this.message = message;
this.flag = flag;
}
public String getMessage() {
return message;
}
public boolean isFlag() {
return flag;
}
}
test-controller 추가 및 /test 경로 추가된 모습
이렇게 매핑해준 경로가 스웨거에 추가 됩니다.
필요한 파라미터가 어떤건지도 알려줍니다.
하지만 이 파라미터가 왜 필요하고 어떤 동작을 위해 필요한지는 필드명만 보고는 어려울 수 있습니다.
1. 필드에 설명 붙여주기. @ApiModel @ApiModelProperty
@ApiModel(description = "이 모델은 Test하기 위한 Dto 입니다.")
public class TestDto {
@ApiModelProperty(notes = "원하는 message 내용을 넣으세요.")
private String message;
@ApiModelProperty(notes = "원하는 boolean 값을 넣으세요.")
private boolean flag;
public TestDto(String message, boolean flag) {
this.message = message;
this.flag = flag;
}
public String getMessage() {
return message;
}
public boolean isFlag() {
return flag;
}
}
Model 버튼을 눌러주면 이렇게 나옵니다.
2. 컨트롤러가 무슨동작을 하는지 알려주기 @Api
기본적으로 컨트롤러의 설명은 컨트롤러의 클래스이름을 따라갑니다.
이 클래스가 무슨 용도를 위한 클래스인지 설명을 수정해줄 수 있습니다.
@RestController
@Api(description = "테스트 하기위한 TestController 예요!")
public class TestController {
3. API 어떤 동작을 하는지 알려주기. @ApiOperation
기본적으로 API 설명은 메소드이름으로 적혀있습니다.
이것 또한 개발자가 수정해줄 수 있습니다.
@ApiOperation("테스트를 하기위한 Api이예요!")
@GetMapping("/test")
public TestDto testGetMethod(@RequestBody TestDto testDto) {
return new TestDto("Test!!",true);
}
4. API 호출이 헤더가 필요할 때 @ApiImplicitParams,@ApiImplicitParam
Oauth2를 사용하신다면 Header에 Token을 넘겨야 합니다.
Swagger 문서에 Header를 명시해주기 위해서는 다음과 같이 사용하시면 됩니다.
@ApiImplicitParams({
@ApiImplicitParam(name = "Authorization", value = "authorization header", required = true,
dataType = "string", paramType = "header", defaultValue = "bearer cbbb1a6e-8614-4a4d-a967-b0a42924e7ca")
})
@ApiOperation("테스트를 하기위한 Api이예요!")
@GetMapping("/test")
public TestDto testGetMethod(@RequestBody TestDto testDto) {
return new TestDto("Test!!",true);
}
5. 파라미터에대해 설명해주기 @ApiParam
API가 필요로하는 파라미터에 대해 설명을 해줄 수 있습니다.
@GetMapping("/test")
public TestDto testGetMethod(@ApiParam(value = "Test대한 정보",required = true)@RequestBody TestDto testDto) {
return new TestDto("Test!!",true);
}
6. 파라미터가 Swagger에 안보이게 하기
파라미터가 여러개 있을 때 원하지 않는 파라미터를 Swagger에서 안보이게 할 수 있습니다.
저는 Oauth2가 받는 파라미터가 보이지 않게 해주고 싶을 때 이용 했습니다.
@GetMapping("/test")
public TestDto testGetMethod(@ApiIgnore Authentication authentication,@RequestBody TestDto testDto) {
return new TestDto("Test!!",true);
}
7. Advanced Swagger Config
7-1. 패키지 기반 문서화 basePackage
현재 Swagger는 Spring이 자동으로 만들어지는 Controller도 문서에 나타나게 됩니다.
이 Controller를 제외하는 방법을 해보겠습니다.
SwaggerConfig.java
@Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("swagger-tutorial_api_v1")
.select() .apis(RequestHandlerSelectors.basePackage("com.donghyeon.swaggertutorial.controller"))
.paths(PathSelectors.any())
.build().apiInfo(apiInfo());
}
지정해준 패키지안에 있는 컨트롤러만 문서화하는 설정입니다.
7-2. /api로 시작하는 API만 문서화하기 ant()
RestAPI들은 보통 /api로 시작하는게 보편적입니다.
/api로 시작하는 API들만 문서화 하는 방법을 알아보겠습니다.
SwaggerConfig.java
@Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("swagger-tutorial_api_v1")
.select() .apis(RequestHandlerSelectors.basePackage("com.donghyeon.swaggertutorial.controller"))
.paths(PathSelectors.ant("/api/**"))
.build().apiInfo(apiInfo());
}
이제 맵핑이 /api 로시작하는것만 문서화가 됩니다,
Trouble Shooting
Swagger에 접속했는데 다음과 오류가 나타날 수 있습니다.
java.lang.NumberFormatException: For input string: ""
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65) ~[na:1.8.0_191]
at java.lang.Long.parseLong(Long.java:601) ~[na:1.8.0_191]
at java.lang.Long.valueOf(Long.java:803) ~[na:1.8.0_191]
at io.swagger.models.parameters.AbstractSerializableParameter.getExample(AbstractSerializableParameter.java:412) ~[swagger-models-1.5.20.jar:1.5.20]
at sun.reflect.GeneratedMethodAccessor149.invoke(Unknown Source) ~[na:na]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_191]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_191]
at
....
이 문제는 springfox-swagger2 라이브러리 안에 있는 swagger-annotations과 swagger-models의
버전충돌 문제로 보입니다.
이 두개의 라이브러리만 구 버전인 1.5.21을 사용하시면 해결됩니다.
해결방법
Gradle
//springfox-swagger2
compile(group: 'io.springfox', name: 'springfox-swagger2', version: '2.9.2') {
exclude group: 'io.swagger' ,module : 'swagger-annotations'
exclude group: 'io.swagger' ,module : 'swagger-models'
}
//springfox-swagger-ui
compile group: 'io.springfox', name: 'springfox-swagger-ui', version: '2.9.2'
// swagger-annotations 1.5.21 / swagger-models 1.5.21
compile group: 'io.swagger', name: 'swagger-annotations', version: '1.5.21'
compile group: 'io.swagger', name: 'swagger-models', version: '1.5.21'
Maven
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
<exclusions>
<exclusion>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
</exclusion>
<exclusion>
<groupId>io.swagger</groupId>
<artifactId>swagger-models</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
<version>1.5.21</version>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-models</artifactId>
<version>1.5.21</version>
</dependency>