-
Notifications
You must be signed in to change notification settings - Fork 0
Swagger2 Configuration
정명주(myeongju.jung) edited this page Apr 30, 2018
·
6 revisions
pom.xml
<properties>
...
<swagger2.version>2.9.0</swagger2.version>
</properties>
<dependencies>
...
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${swagger2.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${swagger2.version}</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
...
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>24.1-jre</version>
</dependency>
</dependencies>
</dependencyManagement>
- 2.9.0 버전으로 추가 시
guava
버전 충돌이 발생하므로 의존성 재정의 요망
build.gradle
ext['springfoxVersion'] = '2.7.0'
dependencies {
compile "io.springfox:springfox-swagger2:${springfoxVersion}"
compile "io.springfox:springfox-swagger-ui:${springfoxVersion}"
// compile "io.springfox.ui:springfox-swagger-ui-rfc6570:1.0.0" // incubating
}
/**
* Swagger2 Configuration
*
* @author myeongju.jung
*/
@SuppressWarnings("Guava")
@Configuration
@ConditionalOnWebApplication
@EnableSwagger2
public class Swagger2Configuration {
@Bean
public Docket allApi() {
return globalConfiguration(
new Docket(DocumentationType.SWAGGER_2)
.groupName("Example SNS API - All")
.apiInfo(apiInfo())
.select()
.paths(allApiPaths())
.build());
}
private Docket globalConfiguration(Docket docket) {
return docket
.directModelSubstitute(ZonedDateTime.class, Long.class)
.ignoredParameterTypes(Pageable.class, UriComponentsBuilder.class, Model.class, UserDetails.class)
.genericModelSubstitutes(ResponseEntity.class)
.useDefaultResponseMessages(false)
.globalResponseMessage(RequestMethod.GET, newArrayList(
new ResponseMessageBuilder()
.code(400)
.message("인자가 유효하지 않는 경우")
.build(),
new ResponseMessageBuilder()
.code(404)
.message("조회할 자원을 찾을 수 없는 경우")
.build(),
new ResponseMessageBuilder()
.code(500)
.message("Internal Server Error")
.build()
))
.globalResponseMessage(RequestMethod.POST, newArrayList(
new ResponseMessageBuilder()
.code(400)
.message("인자가 유효하지 않는 경우")
.build(),
new ResponseMessageBuilder()
.code(404)
.message("연관된 자원을 찾을 수 없는 경우")
.build(),
new ResponseMessageBuilder()
.code(500)
.message("Internal Server Error")
.build()
))
.globalResponseMessage(RequestMethod.PUT, newArrayList(
new ResponseMessageBuilder()
.code(400)
.message("인자가 유효하지 않는 경우")
.build(),
new ResponseMessageBuilder()
.code(404)
.message("변경할 자원을 찾을 수 없는 경우")
.build(),
new ResponseMessageBuilder()
.code(500)
.message("Internal Server Error")
.build()
))
.globalResponseMessage(RequestMethod.DELETE, newArrayList(
new ResponseMessageBuilder()
.code(400)
.message("인자가 유효하지 않는 경우")
.build(),
new ResponseMessageBuilder()
.code(404)
.message("삭제할 자원을 찾을 수 없는 경우")
.build(),
new ResponseMessageBuilder()
.code(500)
.message("Internal Server Error")
.build()
))
;
}
private Predicate<String> allApiPaths() {
return not(or(
regex("/management.*"),
regex("/error.*")
));
}
@Bean
public Docket postApi() {
return globalConfiguration(
new Docket(DocumentationType.SWAGGER_2)
.groupName("Example SNS API - Post")
.apiInfo(apiInfo())
.select()
.paths(postApiPaths())
.build());
}
private Predicate<String> postApiPaths() {
return or(
regex("/posts.*"),
regex("/recommend-posts.*"),
);
}
@Bean
public Docket userApi() {
return globalConfiguration(
new Docket(DocumentationType.SWAGGER_2)
.groupName("Example SNS API - User")
.apiInfo(apiInfo())
.select()
.paths(userApiPaths())
.build());
}
private Predicate<String> userApiPaths() {
return or(
regex("/user.*"),
regex("/post\\-users.*")
);
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("Example SNS API")
.description("적절한 설명 블라블라. html 태그는 사용할 수 없음")
.termsOfServiceUrl("http://example-sns.co.kr")
.contact(new Contact("Example SNS 개발팀", "http://corp.example-sns.co.kr", "dev@example-sns.co.kr"))
.build();
}
}
@Api(tags = "user", description = "사용자")
@RestController
@RequestMapping("/users")
public class UserRestController {
@Autowired
private UserService userService;
/**
* 사용자들 페이징 조회
*/
@ApiOperation("사용자들 페이징 조회")
@ApiImplicitParams({
@ApiImplicitParam(name = "page", value = "페이지 번호(0base)", required = false, defaultValue = "0", dataType = "number", paramType = "query"),
@ApiImplicitParam(name = "size", value = "페이지 당 사이즈", required = false, defaultValue = "10", dataType = "number", paramType = "query")
})
@GetMapping("")
public Page<UserRowDto> list(UserSearch search,
@PageableDefault Pageable pageable) {
return userService.getUserRows(search, pageable);
}
/**
* 사용자 1건 상세 조회
*/
@ApiOperation(value = "사용자 상세 조회")
@GetMapping("/{userId}")
public UserDetail detail(@ApiParam(value = "사용자아이디", required = true) @PathVariable("userId") String userId) {
return userService.getUserDetail(userId);
}
/**
* 사용자 소개글 변경
*/
@ApiOperation(value = "사용자 소개글 변경")
@PutMapping("/{userId}/introduction")
public void modifyIntroduction(@ApiParam(value = "사용자아이디", required = true) @PathVariable("userId") String userId,
@Valid @RequestBody UserIntroduction input) {
userService.modifyIntroduction(userId, input.getValue());
}
/**
* 페이지 신청
*/
@ApiOperation(value = "페이지 신청", notes = "추후 페이지가 승인하면 정식 관리자로써 활성화. 복수 신청해도 멱등성으로 인해 페이지 신청이 인가된다.")
@ApiResponses({
@ApiResponse(code = 403, message = "페이지를 신청할 수 없는 상태인 경우 (휴면, 블랙 등)", response = ErrorModel.class),
@ApiResponse(code = 404, message = "회원이 존재하지 않거나 탈퇴된 경우 발생", response = ErrorModel.class),
@ApiResponse(code = 409, message = "일반적으로 이미 존재하는 페이지인 경우", response = ErrorModel.class)
})
@PostMapping("/pages")
public ResponseEntity createPage(PageCreateRequest param, UriComponentsBuilder uriComponentsBuilder,
@AuthenticationPrincipal UserDetails) {
Page page = pageService.request(param, userDetails);
URI location = getLocation(page, uriComponentsBuilder);
return ResponseEntity.created(location).build();
}
private URI getLocation(Page page, UriComponentsBuilder uriComponentsBuilder) {
return uriComponentsBuilder.path("/pages/{pageId}/")
.buildAndExpand(page.getPageId())
.toUri();
}
}
JAVA
JPA
- JPA-Create-And-Update
- Optional-Eager
- QueryDsl-Configuration
- QueryDsl-More-Type-safety
- QueryDsl-SubQuery
DDD
Install
Spring
Spring-Boot
- Swagger2-Configuration
- Spring-Restdocs-Configuration
- Spring-Page-Jackson
- JSR310-Guide
- logback-spring.xml
- WebMvcUtils.java
- Spring-Boot-Properties
- Spring-Boot-Hidden-Gems
- Spring-Boot-Config
Spring-Cloud
- Spring-Cloud-Zuul
- Spring-Cloud-Feign
- Spring-Cloud-Hystrix
- Spring-Cloud-Consul
- Spring-Cloud-Ribbon
- Spring-Cloud-Circuit-Breaker
JavaScript
Gradle
Test
Linux
Etc
TODO http://zoltanaltfatter.com/2017/06/09/publishing-domain-events-from-aggregate-roots/