티스토리 뷰

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가 문서화된 웹페이지를 확인할 수 있다.

 

Swagger 메인 화면

 

Get 방식 API

 

Post 방식 API

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/07   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
글 보관함