Swagger란 개발한 REST API를 편리하게 문서화해주고, 이를 통해서 관리 및 제3의 사용자가 편리하게 API를 호출해보고 테스트 할 수 있는 API이다.
Spring Boot에서는 간단하게 springfox-boot-starter 를 maven, gradle dependencies에 추가함으로 사용할 수 있다.
다만, 주의할 점은 운영환경과 같은 외부에 노출되면 안되는 곳에는 사용하면 안된다.
id 'org.springframework.boot' version '2.4.4'
springboot 2버전 기준
springfox-swagger2
, springfox-swagger-ui
2개 디팬더시가 필요하다.
<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>
// https://mvnrepository.com/artifact/io.springfox/springfox-swagger2
implementation group: 'io.springfox', name: 'springfox-swagger2', version: '2.9.2'
implementation group: 'io.springfox', name: 'springfox-swagger-ui', version: '2.9.2'
update: Swagger3 버전
위 버전의 디팬더시를 쓰면 springboot 버전을 낮춰야지만 사용할 수있다.
다음 3버전부터 쓰면 그럴 필요가 없다.
implementation 'io.springfox:springfox-boot-starter:3.0.0'
💥 documentationPluginsBootstrapper
- Swagger3 버전 dependacy 추가 후 오류
org.springframework.context.ApplicationContextException: Failed to start bean 'documentationPluginsBootstrapper'; nested exception is java.lang.NullPointerException
원인 : Spring boot 2.6버전 이후에 spring.mvc.pathmatch.matching-strategy 값이 ant_apth_matcher에서 path_pattern_parser로 변경되면서 몇몇 라이브러리에서 오류가 발생한다고 한다.
해결 : application.yml에 아래와 같은 줄 추가
application.yml
spring:
mvc:
pathmatch:
matching-strategy: ant_path_matcher
http://localhost:8090/swagger-ui.html
을 웹브라우저에 치면 나온다.http://localhost:8080/v2/api-docs
http://localhost:8090/swagger-ui/index.html
✅ 이 어노테이션이 안붙인다고 swagger ui에 각 api url 표시가 안나오지는 않습니다!
@Api
: 클래스
를 swagger의 리소스로 표시(표시 나오는 부분이 없음)
@ApiOperation
: 메서드
를 swagger의 리소스로 표시
@ApiResponse
: 메서드
의 응답 지정
@Api(value = "comment controller exposes crud rest-apis")
@RestController
@RequestMapping("/api/")
@RequiredArgsConstructor
public class CommentController {
@ApiOperation(value="AI 전기방식 동작여부 확인", notes="시스템에 등록된 현재 AI 전기방식 상태값 리턴(state:'Y' or 'N'). '../set-state'가 일정 시간 호출되지 않을 경우 N을 리턴.")
@ApiResponses({
@ApiResponse(code = 200, message = "API 정상 작동"),
@ApiResponse(code = 500, message = "서버 에러")
})
@RequestMapping(value="/is-running", method={RequestMethod.GET})
public ResponseEntity<AIRunningVo> isRunning() throws Exception {
AIRunningVo res = new AIRunningVo();
res.setState(AiStateManager.getInstance().getState());
return new ResponseEntity<AIRunningVo>(res, HttpStatus.OK);
}
...
}
빨간색 박스 내용이 @ApiOperation
표시이다.
@ApiModel
: 모델의 데이터 설명
@ApiModelProperty
: 모델의 필드 데이터를 설명
@ApiModel(description = "board AmiDeviceAddVo information")
@Data
@NoArgsConstructor
public class SignUpDto {
@ApiModelProperty(value = "사용자 이름", dataType = "string", required = true, example = "롬복")
private String name;
@ApiModelProperty(value = "사용자 이메일")
private String email;
private String password;
private String role;
}
@ApiModelProperty
내 옵션으로 example
을 설정해주면 Swagger문서의 Example Value 로 나오게 된다!
그리고 그 옆에 Schema 쪽을 누르면 RequestBody로 넣을 클래스 정리가 된 것을 알 수 있다.
swagger 문서 맨 아래 쪽을 가서 Schemas
탭을 눌러서도 정리가 된 것도 알 수 있다.
이 Schemas 탭을 누르고 ~Dto
를 검색(ctrl+F)해서 Dto 정보를 빨리 찾아볼 수있다!
SwaggerConfig
: @EnableSwagger2
사용
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any())
.build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("springBoot-swagger-example ")
.description("description")
.version("1.0")
.build();
}
}
Swagger3 버전
@Configuration
public class SwaggerConfig {
@Bean
public Docket api() {
return new Docket(DocumentationType.OAS_30)
.useDefaultResponseMessages(false)
.select()
.apis(RequestHandlerSelectors.basePackage("com.dsg.wardstudy.controller"))
.paths(PathSelectors.any())
.build()
.apiInfo(apiInfo());
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("swagger-api-Docs")
.description("SwaggerConfig")
.version("1.0") // 문서 버전 관리
.build();
}
}
SecurityConfig있을시 (swagger api 허용 설정)
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers(
"/v2/api-docs",
"/swagger-resources/**",
"/swagger-ui.html",
"/webjars/**",
"/swagger/**",
"/v3/api-docs/**",
"/swagger-ui/**",
"/robot.txt",
"/favicon.ico"
);
}
Authorization (apiKey) 설정
Bearer
{accessToken}
을 넣어줘서 인증을 받아야 한다.
@Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.ignoredParameterTypes(AuthenticationPrincipal.class)
.securityContexts(Arrays.asList(securityContext()))
.securitySchemes(Arrays.asList(apiKey()))
.useDefaultResponseMessages(false)
... // 추가
}
// 추가
private ApiKey apiKey() {
return new ApiKey("Authorization", "Authorization", "header");
}
private SecurityContext securityContext() {
return SecurityContext
.builder()
.securityReferences(defaultAuth()).forPaths(PathSelectors.any()).build();
}
List<SecurityReference> defaultAuth() {
AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
authorizationScopes[0] = authorizationScope;
return Arrays.asList(new SecurityReference("Authorization", authorizationScopes));
}
Try it out
을 누른 다음 Parm 등 value
채우고
Execute
클릭 하면 Response를 확인할 수 있다.
결과(예시로 Response Body, Response Code 등)
👍 POST일시
특히, Swagger를 쓰는 이유 중에 POST방식을 사용하는데 RequestBody
를 지정해주는 것이 편하기 때문인데, 아래 사진을 보면
자동으로 Request Body 필드 들을 생성해주는 것을 볼 수 있다.
이처럼 개발자는 편한게 필드에 대한 내용만 적어 주면 되는 것
이다. 이젠, postman에서 다 작성해야 하는 번거로운 일을 하지 않아도 되는 것이다.