본문 바로가기

Spring

Spring REST API - Swagger2 연동

반응형

기존에 개발했던 Rest API 들은 개발 완료 후 문서화 작업을 통해 API 정의서를 제작했고 신규 유저 연동시에 문서로 spec을 전달했다.

 

하지만 프로그램 수정이 필요할 때 수정되는 내용에 따라 문서도 수정 후 다시 유저에게 재 공지되는 등 불편한 점이 많았다

 

테스트 요청시에도 Junit 과 별도로 Postman/curl 을 통해서 각각 항목별 요청을 진행했는데,

로컬, 테스트서버, 운영서버 등 서버 주소가 변경되거나 환경에 따라 Postman 에 미리 세팅해논 request 파일들을 일일이 수정해야되는 경험이 있어 매우 불편했다.

 

하지만 Swagger라는 문서 자동화 툴을 이번에 접하게되었고 신규 RestAPI 프로젝트가 있어 검토 후 프로젝트에 반영해보려고 한다!


 

필자처럼 Swagger가 처음이라면 Swagger 공식홈페이지에서 Swagger Specification을 먼저 확인하길 바란다.

 

Spring Maven Project로 테스트 진행했다.

 

 

1. Maven dependency 추가

...

<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger2</artifactId>
    <version>2.4.0</version>
</dependency>

<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger-ui</artifactId>
    <version>2.4.0</version>
</dependency>

...

 

2. 스트링 부트 없이 설정

스트링 부트를 사용하지 않는다면 사용자는 Swagger 리소스 핸들러의 자동설정이 되지 않는다.

Swagger UI는 리소스 세트를 추가하는데 이는 사용자가 직접 @WebMvcConfigurerAdapter 를 상속받아 addResourceHandler method를 재 정의 해주어야된다.

@Configuration
@EnableWebMvc
@EnableSwagger2
public class SwaggerConfig extends WebMvcConfigurerAdapter {
    
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");
        registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
    }
    ...
}

 

3. Docket 빈 설정

Swagger 의 주 설정인 Docket Bean 등록 부분이다.

select() method는 Swagger 설정 setting 이후 ApiSelectorBuilder 인스턴스를 리턴한다.

 

1. 전체 범위 포함

@Configuration
@EnableSwagger2
public class SwaggerConfig {                                    
    @Bean
    public Docket api() { 
        return new Docket(DocumentationType.SWAGGER_2)  
          .select()                                  
          .apis(RequestHandlerSelectors.any())              
          .paths(PathSelectors.any())                          
          .build();                                           
    }
}

 

2. 범위 설정(paths, api class or base package)

@Configuration
@EnableSwagger2
public class SwaggerConfig {

    @Bean
    public Docket api() {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .select()
                .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
                .build()
                .useDefaultResponseMessages(false)
                .globalResponseMessage(RequestMethod.GET,
                        Arrays.asList(
                                new ResponseMessageBuilder()
                                        .code(500)
                                        .message("server error")
                                        .responseModel(
                                                new ModelRef("Error")
                                        ).build()
                        )
                );
    }

    private ApiInfo getApiInfo() {
        return new ApiInfoBuilder()
                .title("Swagger")
                .description("api list")
                .contact(new Contact("jhPark", "https://jhparkkk.tistory.com", "junghun5947@gmail.com"))
                .version("1.0.0")
                .build();
    }
}

 

1. api()

1. apiInfo  : API 정보

2. useDefaultResponseMessages : 기본 반환 Message 설정

3. globalResponseMessage : 전반적인 반환 Message 셋팅

  - RequestHandlerSelectors.any() : 모든 url

  - RequestHandlerSelectors.none() : 사용 X

  - RequestHandlerSelectors.basePackage(String path) : path 에 해당하는 단위

4. apis

5. paths(Predicate selector) : PathSelectors 를 이용하여 path 에 대한 설정 가능 (**/api/*, /api/v1/* ..)

 

2. getApiInfo()

contact : 작성자 정보 

 


4. Controller 설정

다음과 같이 Controller class에 annotation @Api 추가 ( 속성-  value, description, tags, hidden )

@Api(value = "main", description = "main controller description")
public class MainController {
	....
}

 

API method 설정

@ApiOperation(value = "사용자 정보 리스트", notes = "사용자 정보 요청 API")
@RequestMapping(value = "/account", method = RequestMethod.POST, headers ="Accept=application/json")
public @ResponseBody String getAccount() throws Exception{
 	...
	return result;
}

@ApiOperation(value = "사용자 정보 입력", notes = "사용자 정보 입력 API")
@RequestMapping(value = "/setAccount", method = RequestMethod.POST, headers ="Accept=application/json")
public @ResponseBody String setAccount(@ApiParam(value="사용자 이름", required = true) @RequestParam String uName,
									   @ApiParam(value="사용자 아이디", required = true) @RequestParam String uId
										throws Exception{
 	...
	return result;
}

1. @ApiOperation(value = “사용자 정보 리스트”, notes = “사용자 정보 요청 API”)
   각각의 resource에 제목과 설명을 표시하기 위해 세팅한다.
2. @ApiParam(value = “사용자 이름”, required = true) @RequestParam ~~~
   입력받는 파라미터에 대한 설명을 보여주기 위해 세팅한다.

 


5. 검증

스프링 폭스가 동작하는지 검증하기 위해 다음의 URL을 브라우저로 접속

http://localhost:8080/your-app-root/v2/api-docs

JSON 데이터 형식으로 구성된 설정완료된 정보를 확인할 수 있다.

 


6. Swagger UI

api-docs url의 API data를 UI로 확인할 수 있는 내장 솔루션이다.

프로젝트 서버를 실행 후 다음 링크에서 확인해보자.

http://localhost:8080/your-app-root/swagger-ui.html
정상적으로 자신이 추가한 Controller 정보가 나온다면 설정에 성공한 것이다.

 

 

Swagger2 설정에 대해 알아봤다.

간단한 설정으로 기존에 운영중이던 프로젝트 혹은 신규 프로젝트에 어렵지 않게 적용할 수 있었다.

반응형