티스토리 뷰
웹 서비스 개발하기에 앞서, API 개발과 RESTfull API를 문서화 할 수 있는 Swagger 를 먼저 설정한 후 진행 할 예정이다.
API 문서를 완성하고 스펙이 변경 될 때 마다 문서를 수정하는건 엄청나게 귀찮은 일이기 때문에.....
Swagger 의 경우, 내가 생각하는 장점은 아래와 같다.
- Swagger 를 적용한 MSA 기반 API 서버에서, 간단한 설정만으로 UI 제공
- Swagger-UI 는 API 의 스펙을 확인할 수 있고, 파라미터 입력 후 실행할 수 있다 (RestClient 툴을 사용안해도 됨!)
- 간단한 Annotation 을 통해 문서에 표기할 수 있고, 주석(?)을 겸할 수 있다.
- 개발과 동시에 문서까지 적용하는 일거 양득 !!
- 쉽게 적용할 수 있고, 사용법도 엄청나게 간단 하다.
- Swagger UI 가 이쁨
실제 업무에서도 많이 쓰고 있기 때문에, 경험해보지 못한 분들이라면 꼭 써보라고 추천함 ++
아참, 그리고 이전장에서 프로젝트 생성한 부분에 패키지 및 파일명을 변경하는 작업도 이번에 같이할거임.
1. Gradle 설정
프로젝트 build.gradle 파일 dependencies 하위에 swagger 정보를 추가해주자.
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-web'
// swagger
compile("io.springfox:springfox-swagger2:2.9.2")
compile("io.springfox:springfox-swagger-ui:2.9.2")
compileOnly 'org.projectlombok:lombok'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
runtimeOnly 'com.h2database:h2'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
2. Config 설정
com.mellowp.bookstore 하위에 config 패키지를 추가한 후, "SwaggerConfiguration" 클래스를 생성.
@Configuration
@EnableSwagger2
public class SwaggerConfiguration {
@Bean
public Docket apiDocket(){
return new Docket(DocumentationType.SWAGGER_2)
.select()
// Api Annotation 으로 선언된 부분만 swagger 로 노출되도록 설정
.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
.paths(PathSelectors.any())
.build()
.useDefaultResponseMessages(false)
.enableUrlTemplating(false)
.apiInfo(new ApiInfoBuilder()
.title("BookStore Rest API")
.version("0.1")
.description("<pre style=\"font-size: .85em;line-height: 1.2em;\">Global Response Entity : <code>{\"code\":{결과코드},\"isOk\":{결과여부},\"message\":{결과메세지},\"body\":{데이터}}</code></pre>")
.build()
);
}
}
Swagger2 는 @EnableSwagger2 어노테이션으로 설정이 가능하며, @Configuration 을 통해 등록되게끔 클래스위에
추가 하였다. 또한 Swagger 의 각 종 설정 같은 경우, Docket 을 통해 가능하게 된다.
.select()
ApiSelectorBuilder 인스턴스를 리턴하며, endpoint를 제어하는 역할을 한다.
.apis()
RequestMapping 으로 할당된 모든 URL 리스트 중, RequestHandlerSelectors 를 통해 적용할 패키지를 선택할 수 있다.
나의 경우, @ApiOperation 어노테이션이 붙은 부분만 노출 되도록 선언 하였다.
- RequestHandlerSelectors.any() : 전체 적용
- RequestHandlerSelectors.none() : 전체 미적용
- RequestHandlerSelectors.basePackage(String path) : path 에 해당하는 부분만 적용
.paths()
위에 언급한 apis() 메소드를 통해 적용할 URL 목록이 오게 되고, 이에 대한 필터링을 적용할 수 있다.
나는 필터링을 하지 않았지만, 아래와 같이 필터링 할 수도 있다.
- PathSelectors.ant("/api/*")
.useDefaultResponseMessage()
디폴트로 반환할 메세지를 설정할건지에 대한 여부를 묻는다.
.enableUrlTemplating(false)
@RequestParam 또는 @ModelAttribute 사용 시 path가 아래와 같이 나오기 때문에, 나는 Fasle 로 설정 하였다.
GET /user/{id}/info{?startDate,endDate}
.apiInfo()
ApiInfoBuilder 를 통해 API 에 대한 설명을 진행할 수 있다.
3. Controller 설정
bookstore 하위에 web 과 api 패키지를 생성하고, api 패키지 하위로는 controller 패키지를 추가로 생성 한다.
bookstore.api.controller 에 BookController 클래스를 생성후 아래와 같이 작성.
@RestController
@Api(tags = "/v1 Book API")
@RequestMapping(produces = MediaType.APPLICATION_JSON_VALUE)
@ApiResponses(value = { @ApiResponse(code = 404, message = "Not Found"),
@ApiResponse(code = 500, message = "Internal Server Error") })
public class BookStoreController {
@GetMapping("/v1/book/list")
@ApiOperation(value = "도서 목록 조회", response = List.class, notes = "/v1 도서 목록 조회")
public List<Map<String, String>> searchBookList(){
return Arrays.asList(
ImmutableMap.<String, String>builder().put("title", "Book 01").put("author", "Lion").build(),
ImmutableMap.<String, String>builder().put("title", "Book 02").put("author", "Lion").build(),
ImmutableMap.<String, String>builder().put("title", "Book 03").put("author", "Lion").build()
);
}
@GetMapping("/v1/book/info")
@ApiOperation(value = "도서 상세 조회", response = Map.class, notes = "/v1 도서 상세 조회")
public Map<String, String> searchBookInfo(@RequestParam(value = "num") String num){
return null;
}
@PostMapping("/v1/book/create")
@ApiOperation(value = "도서 등록", response = Boolean.class, notes = "/v1 도서 등록")
public Boolean createBook(){
return true;
}
@PutMapping("/v1/book/modify")
@ApiOperation(value = "도서 정보 수정", response = Boolean.class, notes = "/v1 도서 정보 수젇")
public Boolean modifyBook(){
return true;
}
@DeleteMapping("/v1/book/remove")
@ApiOperation(value = "도서 정보 삭제", response = Boolean.class, notes = "/v1 도서 정보 삭제")
public Boolean removeBook(){
return true;
}
}
아직 서비스를 구현하기 전이고, 임시로 endPoint 만 만들어서 swagger-ui 를 확인하기 위해 test 성으로 추가 하였다.
파라미터 및 응답 DTO 에도 Annotation 을 사용해 작성하게 되면 swagger-ui 에서 상세하게 볼 수 있기 때문에,
이 부분에 대한 확인은 서비스 개발 중반부에 다시 확인하여 비교하도면 될 것 같다.
4. swagger-ui 확인
해당 프로젝트를 bootRun 한뒤, 주소창에 http://localhost:8080/swagger-ui.html 으로 접속을 통해 확인 하자 !!
아래에 보면 apiInfo 에 설정한 화면이 메인상단에 노출되며 html 코드도 적용이 되는 부분을 볼 수 있다.
컨트롤러 별로 분류하여 상세 EndPoint 가 노출되는 형식이며, 색깔별로 Mehtod 방식을 구분할 수도 있고, 맨 하단에
Models 부분으로 해당 API 에서 사용하고 있는 모델 부분들도 한눈에 확인이 가능하게 된다.
위에 메인 화면에서 API 를 선택하면, 아래 그림처럼 열리게 되고 이 화면을 통해서 API 테스트 실행 및 스펙을 확인할 수 있다.
실행(Excute)을 할 경우, Curl 과 Request Url 방식을 보여주고 실행한 결과는 Response Body 에 노출이 된다.
만약 API에서 파라미터 정보가 존재할 경우, 입력할 수 있는 칸이 생성되며 필수값에는 * 로 표기가 되어있는 부분도
확인이 가능하다. 추가로 더 상세하게 확인해보고 싶다면 아래 링크를 참조하면 많은 도움이 될 것이다.
참조: https://www.baeldung.com/swagger-2-documentation-for-spring-rest-api
'프로그래밍 > Spring' 카테고리의 다른 글
JWT(Json Web Token) 소개 및 활용 (2) | 2021.04.28 |
---|---|
[Spring Boot] 웹 서비스 개발(2) - Git Repository (0) | 2019.10.09 |
[Spring Boot] 웹 서비스 개발(1) -프로젝트 생성 (0) | 2019.10.08 |
스프링 프레임워크 간략 정의 (0) | 2019.09.29 |
- Total
- Today
- Yesterday