티스토리 뷰
Swagger (스웨거) 는 Open Api Specification (OAS) 를 위한 프레임워크로 API 의 Spec (스펙) 을 명세, 관리, 문서화 할 수 있는 프로젝트이다.
Swagger (스웨거) 가 유용하게 사용되는 경우
- 백엔드의 API 를 호출하는 프론트엔드를 개발하는 경우
- 프로젝트의 유지보수를 진행하는 경우
- 외부 다른 개발팀과 현업하는 경우
0. 개발 환경
개발 언어 : JAVA
개발 툴 : STS (Spring Tool Suite)
개발 프레임워크 : Spring Boot (Maven)
개발 DB : MariaDB
1. Maven 설정
pom.xml 에 아래 코드 추가
<!-- Swagger 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>
2. SwaggerConfig.java 생성
package com.team.wtd.swagger.config;
import java.util.ArrayList;
import javax.servlet.ServletContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration
@EnableSwagger2
public class SwaggerConfig extends WebMvcConfigurationSupport {
//TODO 아래 String 값 프로퍼티 화
private String title = "사이트 제목";
private String description = "사이트 설명";
private String version = "0.1 BETA";
private String termsOfServiceUrl = "사이트 주소";
private String name = "사이트 운영자 이름";
private String url = "사이트 주소";
private String email = "사이트 운영자 이메일";
private String license = "사이트 라이센스";
private String licenseUrl = "사이트 라이센스 URL";
@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/");
super.addResourceHandlers(registry);
}
@Bean
public Docket api1(ServletContext servletContext) {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo(title, version))
.groupName("groupName1")
.select()
.apis(RequestHandlerSelectors.basePackage("com.team.wtd"))
.paths(PathSelectors.ant("/api1/**"))
.build();
}
@Bean
public Docket api2(ServletContext servletContext) {
return new Docket(DocumentationType.SWAGGER_2)
.useDefaultResponseMessages(false)
.apiInfo(apiInfo(title, version))
.groupName("groupName2")
.select()
.apis(RequestHandlerSelectors.basePackage("com.team.wtd"))
.paths(PathSelectors.ant("/api2/**"))
.build();
}
private ApiInfo apiInfo(String title, String version) {
return new ApiInfo(title, description, version, termsOfServiceUrl,
new Contact(name, url, email), license,
licenseUrl, new ArrayList<>());
}
}
@EnableSwagger2
- Swagger2 버전을 활성화 하겠다는 어노테이션이다.
Docket
- Swagger 설정을 할 수 있게 도와주는 클래스이다.
- API 자체에 대한 정보는 컨트롤러에서 작성한다.
useDefaultResponseMessages()
- false로 설정하면 Swagger에서 제공해주는 응답코드(200, 401, 403, 404)에 대한 기본 메시지를 제거해준다.
groupName()
- Docket Bean이 한 개일 경우 생략해도 상관없으나, 둘 이상일 경우 충돌을 방지해야 하므로 설정해줘야 한다.
apiInfo()
- 제목, 설명 등 문서에 대한 정보들을 설정하기 위해 호출한다.
select()
- ApiSelectorBuilder를 생성하여 apis()와 paths()를 사용할 수 있게 해준다.
apis()
- api 스펙이 작성되어 있는 패키지를 지정한다.
- 즉, 컨트롤러가 존재하는 패키지를 basepackage로 지정하여 해당 패키지에 존재하는 API를 문서화 한다.
paths()
- apis()로 선택되어진 API중 특정 path 조건에 맞는 API들을 다시 필터링하여 문서화한다.
- PathSelectors.any()로 설정하면 패키지 안에 모든 API를 한 번에 볼 수 있다.
ParameterBuilder + globalOperationParameters()
- parameterBuilder와 globalOperationParameters()를 이용해서 아래와 같이 Swagger의 전체 API에서 보여줄 파라미터를 설정해줄 수도 있다.
@Bean
public Docket api() {
ParameterBuilder ParameterBuilder = new ParameterBuilder();
ParameterBuilder.name("X-ACCESS-TOKEN") // 헤더 이름
.description("X-ACCESS-TOKEN") // 설명
.modelRef(new ModelRef("string"))
.parameterType("header")
.required(false)
.build();
List<Parameter> parameterList = new ArrayList<>();
parameterList.add(ParameterBuilder.build());
return new Docket(DocumentationType.SWAGGER_2)
.globalOperationParameters(parameterList)
globalResponseMessage()
- 아래와 같이 globalResponseMessage()로 모든 operation에 공통된 응답 메시지를 작성해줄 수도 있다.
@Bean
public Docket apiV1() {
List<ResponseMessage> responseMessages = new ArrayList<>();
responseMessages.add(new ResponseMessageBuilder()
.code(200)
.message("OK")
.build());
responseMessages.add(new ResponseMessageBuilder()
.code(404)
.message("Not Found Error")
.build());
responseMessages.add(new ResponseMessageBuilder()
.code(500)
.message("Internal Server Error")
.build());
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo(title, version))
.groupName("groupName1")
.select()
.apis(RequestHandlerSelectors.basePackage("com.team.wtd"))
.paths(PathSelectors.ant("/api1/**"))
.build();
.globalResponseMessage(RequestMethod.GET, responseMessages);
}
3. Controller 설정
package com.team.wtd.user.controller;
import java.util.HashMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.team.wtd.user.service.UserServiceImpl;
import com.team.wtd.user.vo.UserVo;
import io.swagger.annotations.ApiParam;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
@RestController
@RequestMapping("/api1/user")
public class UserController {
@Autowired
private UserServiceImpl userService;
@ApiOperation(httpMethod = "GET"
,value = "로그인"
,notes = "로그인을 위한 API 이다.")
@ApiResponses(value = {
@ApiResponse(code = 200, message = "Suceess|OK"),
@ApiResponse(code = 401, message = "not authorized!"),
@ApiResponse(code = 500, message = "Server Error!!!")})
@GetMapping("/login")
public HashMap<String, Object> loginGet(@ApiParam(name = "유저 아이디", value = "id", required = true) String userId,
@ApiParam(name = "유저 비번", value = "pw", required = true) String userPw) {
HashMap<String, Object> loginSession = new HashMap<String, Object>();
UserVo sessionUser = userService.login(userId, userPw);
String loginResult = "";
if(sessionUser == null) {
loginResult = "로그인 실패 : 없는 유저입니다.";
} else {
loginResult = "로그인 성공";
}
loginSession.put("loginResult", loginResult);
loginSession.put("sessionUser", sessionUser);
return loginSession;
}
@ApiOperation(httpMethod = "POST"
,value = "로그인"
,notes = "로그인을 위한 API 이다.")
@ApiResponses(value = {
@ApiResponse(code = 200, message = "Suceess|OK"),
@ApiResponse(code = 401, message = "not authorized!"),
@ApiResponse(code = 500, message = "Server Error!!!")})
@PostMapping("/login")
public HashMap<String, Object> loginPost(@RequestBody UserVo userVo) {
HashMap<String, Object> loginSession = new HashMap<String, Object>();
UserVo sessionUser = userService.login(userVo.getUser_id(), userVo.getUser_pw());
String loginResult = "";
if(sessionUser == null) {
loginResult = "로그인 실패 : 없는 유저입니다.";
} else {
loginResult = "로그인 성공";
}
loginSession.put("loginResult", loginResult);
loginSession.put("sessionUser", sessionUser);
return loginSession;
}
}
@ApiOperation
- 한 개의 Operation을 선언한다.
- httpMethod : API 방식을 입력한다. (생략 가능, 생략 시 Mapping 으로 자동 지정)
- value : API에 대한 요약을 작성한다. 제대로 표시되려면 120자 이하여야 한다.
- notes : API에 대한 자세한 설명을 작성한다.
@ApiParam
- Get 방식일 때 파라미터에 대한 정보를 명시한다.
- name : 파라미터 이름을 작성한다.
- value : 파라미터 설명을 작성한다.
- required : 필수 파라미터이면 true, 아니면 false를 작성한다.
@RequestBody
- Post 방식일 때 파라미터에 대한 정보를 명시한다.
- Vo : 객체로 받아 데이터를 넘겨준다.
@ApiResponses
- 각각 API 별로 응답 메시지 입력한다. (생략 가능)
4. 결과 화면
ex) http://localhost:8282/swagger-ui.html
실행 시킨 서버의 IP와 Port 번호로 입력한 후 /swagger-ui.html 로 들어가서 API가 문서화된 웹페이지를 확인할 수 있다.
댓글