내가 API를 작성했으면, 해당 API대로 요청이 들어와야 한다.
해당 API가 아니면, 내가 만든 프로젝트는 요청이 와도 이해할 수 없기 때문이다.
예를 들어,
멤버 등록을 /members 라고 지정했는데,
/members/create 라고 요청이 들어오면,
내 프로젝트에선
이 요청은 뭐라는거지? 메뉴판에 있지도 않은 일을 시켜버리네 ㅋㅋ 할줄 몰라!
가 되어버린다.
그래서 이번엔!
해당 API대로 주문 부탁드릴게요~! 🙏 🙏 🙏 🙏 🙏 🙏
를 실행하기 위해
남들에게 어떻게 API가 구성되어있고 어떻게 작동하는지를 알려주기 위한
API문서화를
Swagger 라이브러리를 통해 구현할거다.
가장 먼저 swagger 의존성을 추가한다 (gradle)
implementation'io.springfox:springfox-swagger2:2.9.2' //swagger
implementation'io.springfox:springfox-swagger-ui:2.9.2' //swagger
그다음 swagger에 대한 설정을 해주는 swaggerConfig 클래스를 다음과 같이 작성했다
이해 쉽게 주석
@Configuration
@EnableSwagger2
public class SwaggerConfig { // Swagger
private static final String API_NAME = "soloProject API";
private static final String API_VERSION = "0.0.1 초기버전";
private static final String API_DESCRIPTION = "soloProject API 명세서";
@Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.basePackage("com.soloProject.server")) // Swagger를 적용할 클래스의 package명
.paths(PathSelectors.any()) // 해당 package 하위에 있는 모든 url에 적용
.build()
.apiInfo(apiInfo());
}
public ApiInfo apiInfo() { // API의 이름, 현재 버전, API에 대한 정보
return new ApiInfoBuilder()
.title(API_NAME)
.version(API_VERSION)
.description(API_DESCRIPTION)
.build();
}
}
그다음 컨트롤러에서 애너테이션으로 다음과 같이 API에 대한 설명을 붙여주면 된다.
이해가 쉽도록 주석을 달아놓았다
@RestController
@Slf4j
@Validated
@Transactional
@RequiredArgsConstructor
@RequestMapping("/products")
@Api(tags = {"재고 API Test"}) // Swagger 최상단 Controller 명칭
public class ProductController {
private final static String PRODUCT_DEFAULT_URL = "/products";
@Autowired
ProductService productService;
@PostMapping
@ApiOperation(value = "물건 등록", notes = "물건 등록 API")
public ResponseEntity postProduct(@Valid @RequestBody ProductDto.Create productPostDto) {
Product createProduct = productService.createProduct(productPostDto);
URI location = UriCreator.createUri(PRODUCT_DEFAULT_URL, createProduct.getProductId());
return ResponseEntity.created(location).build();
}
@PatchMapping("/sell/{product-id}/{member-id}/{quantity}")
@ApiOperation(value = "재고 판매", notes = "재고 판매 API") // Swagger에 사용하는 API에 대한 간단 설명
@ApiImplicitParams( // Swagger에 사용하는 파라미터들에 대해 설명
{
@ApiImplicitParam(name = "member-id", value = "멤버 아이디"),
@ApiImplicitParam(name = "product-id", value = "재고 물품 아이디"),
@ApiImplicitParam(name = "quantity", value = "판매 재고 수량")
})
public ResponseEntity sellProduct(@PathVariable("member-id") @Positive long memberId,
@PathVariable("product-id") @Positive long productId,
@PathVariable("quantity") @Positive int quantity) {
Product patchProduct = productService.sellProduct(memberId, productId, quantity);
URI location = UriCreator.createUri(PRODUCT_DEFAULT_URL, patchProduct.getProductId());
return ResponseEntity.created(location).build();
}
@PatchMapping("/buy/{product-id}/{member-id}/{quantity}")
@ApiOperation(value = "재고 구매", notes = "재고 구매 API")
@ApiImplicitParams(
{
@ApiImplicitParam(name = "member-id", value = "멤버 아이디"),
@ApiImplicitParam(name = "product-id", value = "재고 물품 아이디"),
@ApiImplicitParam(name = "quantity", value = "구매 재고 수량")
})
public ResponseEntity buyProduct(@PathVariable("member-id") @Positive long memberId,
@PathVariable("product-id") @Positive long productId,
@PathVariable("quantity") @Positive int quantity) {
Product patchProduct = productService.buyProduct(memberId, productId, quantity);
URI location = UriCreator.createUri(PRODUCT_DEFAULT_URL, patchProduct.getProductId());
return ResponseEntity.created(location).build();
}
}
위와 비슷하게 모든 Controller에 설명을 붙여주고
어플리케이션을 실행했다.
그런데
Failed to start bean 'documentationPluginsBootstrapper'; nested exception is java.lang.NullPointerException
라는 에러가 나왔다.
구글링 결과,
spring.mvc.pathmatch.matching-strategy 값이
ant_apth_matcher에서 path_pattern_parser로 변경되면서
발생하는 오류였다.
해당 오류 해결에 대한 코드는 아래의 사진과 같다.
spring:
mvc:
pathmatch:
matching-strategy: ant_path_matcher
즉, 이전처럼 ant_apth_matcher으로 설정해줘야 한다.
해당 오류에 관한 설명은,
springboot의 버전이 높아지며 다양한 MVC 패턴 전략이 만들어지며,
이전엔 기본값이 AntPathMatcher(내가 직접 변경해준것) 이었지만,
지금은 기본값이 PathPatternParser(변경 안해줄시 기본값) 이라고 한다.
출처 : https://godekdls.github.io/Spring%20Boot/developing-web-applications/
이렇게 작성을 마치고 코드를 실행시켜
http://localhost:8080/swagger-ui.html
를 들어가보면,
이런식으로 내 API에 대해 설명해주고 있다.
그다음, html 문서화를 진행하고 싶다! 라고 생각하면
아까 들어갔던
http://localhost:8080/swagger-ui.html 에서,
사진의 링크
http://localhost:8080/v2/api-docs를 들어간다.
그럼 사진과 같이 수많은 json을 볼 수 있는데,
우클릭을 통해 다른이름으로 저장하기를 클릭해 json 문서를 저장해준다.
swagger editor url로 진입 후
화면에서 상단 File -> Import file 선택 -> 미리 저장해둔 json 파일을 선택한다. (위의 사진)
로드 이후 html 파일로 출력하는게 목표 이므로 상단 Generate Client -> html2 를 선택한다. (위의 사진)
압축을 풀고, html 문서가 만들어진것을 확인할 수 있다.
이제 문서화까지 완료했다.
남은 내용은 AWS 에 관한 설정들과
CI/CD를 위한 젠킨스와의 연동
까지 남은 것 같다.
처음 ERD 설계부터, 빌드 배포 자동화까지 하려다보니 힘들지만
아는 내용은 더 확실히 더 잘 알게 되고
모르는 내용은 알게 되어가는 그런 과정인 것 같다.
글이 잘 정리되어 있네요. 감사합니다.