์ƒˆ์†Œ์‹

Back-End/Spring

[Spring] ์Šค์›จ๊ฑฐ(Swagger) ์„ค์ •

  • -

 

 

 

[Spring] ์Šค์›จ๊ฑฐ(Swagger) ์„ค์ •

 

 

๋งค๋ฒˆ Thymeleaf, Jsp, Pebble, Freemarker ๋“ฑ๋“ฑ ํ…œํ”Œ๋ฆฟ ์—”์ง„๋งŒ ์‚ฌ์šฉํ•˜๋‹ค ๋ณด๋‹ˆ ํผ๋ธ”๋ฆฌ์‹ฑ ์ž‘์—…๋ณธ์„ ๋ฐ›์•„์„œ ์‚ฌ์šฉ์ž ํ™”๋ฉด์„ ์™„์„ฑํ•˜๋Š” ์ž‘์—…์„ ์ฃผ๋กœ ํ•˜๊ฒŒ ๋์—ˆ๋Š”๋ฐ, ์ด๋ฒˆ์—๋Š” ์ƒˆ๋กญ๊ฒŒ JPA์™€ React ๋˜๋Š” Vue๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Back / Front๋ฅผ ๋ช…ํ™•ํ•˜๊ฒŒ ๋ถ„๋ฆฌํ•˜๊ณ  Back ์ชฝ์—์„œ๋Š” Front ์ชฝ์œผ๋กœ API ๊ทœ๊ฒฉ์„œ๋งŒ ์ „๋‹ฌํ•˜๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

 

์ด๋•Œ, ์‚ฌ์ด๋“œ ํ”„๋กœ์ ํŠธ๋กœ ์ง„ํ–‰ํ•˜๋‹ค ๋ณด๋‹ˆ๊นŒ ์‹œ๊ฐ„์  ์—ฌ์œ ๊ฐ€ ๋งŽ์ง€๊ฐ€ ์•Š์•„์„œ API ์—ฐ๋™๊ทœ๊ฒฉ์„œ๊นŒ์ง€ ์ž‘์„ฑํ•˜๊ธฐ์—๋Š” ์–ด๋ ค์›€์ด ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. (ํ•‘๊ณ„์ธ๊ฑฐ ๋‹ค๋“ค ์•„์‹œ์ฃ ?)

 

ํ•ด์„œ.. ์ด๋ฒˆ ๊ธฐํšŒ์— ์Šค์›จ๊ฑฐ(Swagger) API๋ฅผ ํ™œ์šฉํ•ด์„œ API ์—ฐ๋™๊ทœ๊ฒฉ์„œ๋Š” Swagger์—๊ฒŒ ๋งก๊ฒจ๋ณด๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

 

 


#1. Swagger ์„ค์ •

 

1. gradle ์„ค์ •

// swagger
implementation 'io.springfox:springfox-boot-starter:3.0.0'
implementation 'io.springfox:springfox-swagger-ui:3.0.0'

 

2. maven ์„ค์ •

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

 

3. SwaggerConfig.java ์ž๋ฐ”ํŒŒ์ผ ์ƒ์„ฑ ๋ฐ ์„ค์ •

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;

import java.util.HashSet;
import java.util.Set;

/**
 * ์Šค์›จ๊ฑฐ ์„ค์ •
 * @ApiIgnore ๋ฅผ ํ†ตํ•ด์„œ ์ œ์™ธ ๊ฐ€๋Šฅ
 */
@Configuration
@EnableWebMvc
public class SwaggerConfig {

    private ApiInfo swaggerInfo() {
        return new ApiInfoBuilder()
                .title("SAMPLE API")
                .description("SAMPLE API Docs")
                .version("1.0")
                .build();
    }

    @Bean
    public Docket swaggerApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .consumes(getConsumeContentTypes())
                .produces(getProduceContentTypes())
                .apiInfo(swaggerInfo())
                .select()
                .apis(RequestHandlerSelectors.basePackage("kr.co.sample"))
                .paths(PathSelectors.any())
                .build()
                .useDefaultResponseMessages(false);
    }

    private Set<String> getConsumeContentTypes() {
        Set<String> consumes = new HashSet<>();
        consumes.add("application/json;charset=UTF-8");
        consumes.add("application/x-www-form-urlencoded");
        return consumes;
    }

    private Set<String> getProduceContentTypes() {
        Set<String> produces = new HashSet<>();
        produces.add("application/json;charset=UTF-8");
        return produces;
    }
}
  • .apis()๋Š” Swagger API ๋ฌธ์„œ๋กœ ๋งŒ๋“ค๊ธฐ ์›ํ•˜๋Š” BasePackage ๊ฒฝ๋กœ. (ํ•„์ˆ˜)
  • .path()๋Š” URL ๊ฒฝ๋กœ๋ฅผ ์ง€์ •ํ•˜์—ฌ ํ•ด๋‹น URL์— ํ•ด๋‹นํ•˜๋Š” ์š”์ฒญ๋งŒ Swagger API ๋ฌธ์„œ๋กœ ๋งŒ๋“ ๋‹ค. (ํ•„์ˆ˜)
  • .apiInfo()๋Š” Swagger API ๋ฌธ์„œ์— ๋Œ€ํ•œ ์„ค๋ช…์„ ํ‘œ๊ธฐํ•˜๋Š” ๋ฉ”์†Œ๋“œ. (์„ ํƒ)
  • .consume()๊ณผ .produces()๋Š” ๊ฐ๊ฐ Request Content-Type, Response Content-Type์— ๋Œ€ํ•œ ์„ค์ •. (์„ ํƒ)
300x250

 


#2. Swagger Annotations ์ข…๋ฅ˜

 

1. @ApiOperation

@ApiOperation(
    value = "์‚ฌ์šฉ์ž ์ •๋ณด ์กฐํšŒ"
    , notes = "์‚ฌ์šฉ์ž์˜ ID๋ฅผ ํ†ตํ•ด ์‚ฌ์šฉ์ž์˜ ์ •๋ณด๋ฅผ ์กฐํšŒํ•œ๋‹ค."
)
  • ๋ฉ”์†Œ๋“œ ์„ค๋ช… ์–ด๋…ธํ…Œ์ด์…˜

 

 

2. @ApiImplicitParam

//๋‹จ์ผ
@ApiImplicitParam(
	name = "id"
	, value = "์‚ฌ์šฉ์ž ์•„์ด๋””"
	, required = true
	, dataType = "string"
	, paramType = "path"
	, defaultValue = "None"
)

//๋ณต์ˆ˜๊ฐœ
@ApiImplicitParams({
	@ApiImplicitParam(
		name = "id"
		, value = "์ž๊ฒฉ์ฆ ์•„์ด๋””"
		, required = true
		, dataType = "string"
		, paramType = "path"
		, defaultValue = "None"
	),
	@ApiImplicitParam(
		name = "fields"
		, value = "์‘๋‹ต ํ•„๋“œ ์ข…๋ฅ˜"
		, required = false
		, dataType = "string"
		, paramType = "query"
		, defaultValue = ""
	)
})
  • Request Parameter ์„ค๋ช… ์–ด๋…ธํ…Œ์ด์…˜
  • dataType, paramType, required์˜ ๊ฒฝ์šฐ ํ•ด๋‹น name์˜ ์ •๋ณด๊ฐ€ ์ž๋™์œผ๋กœ ์ฑ„์›Œ์ง€๋ฏ€๋กœ ์ƒ๋žต ๊ฐ€๋Šฅ
  • @ApiImplictParams๋กœ @ApiImplictParam์„ ๋ณต์ˆ˜๊ฐœ ์‚ฌ์šฉ ๊ฐ€๋Šฅ

 

 

3. @ApiResponse

//๋‹จ์ผ
@ApiResponse(
	code = 200
	, message = "์„ฑ๊ณต์ž…๋‹ˆ๋‹ค."
)

//๋ณต์ˆ˜๊ฐœ
@ApiResponses({
	@ApiResponse(code = 200, message = "์„ฑ๊ณต์ž…๋‹ˆ๋‹ค.")
	, @ApiResponse(code = 400, message = "์ ‘๊ทผ์ด ์˜ฌ๋ฐ”๋ฅด์ง€ ์•Š์Šต๋‹ˆ๋‹ค.")
})
  • Response ์„ค๋ช… ์–ด๋…ธํ…Œ์ด์…˜
  • useDefaultResponseMessages(false)๋ฅผ SwaggerConfig.java์— ์„ค์ •ํ•ด ์ฃผ๋ฉด, @ApiResponse๋กœ ์„ค๋ช…ํ•˜์ง€ ์•Š์€ 401, 403, 404 ์‘๋‹ต๋“ค์ด ์‚ฌ๋ผ์ง

 

 

4. @ApiParam

@ApiParam(value = "์‚ฌ์šฉ์ž ID", required = true)
  • Dto Field ์„ค๋ช…
  • @ApiParam Annotation์œผ๋กœ DTO์˜ field์— ๋Œ€ํ•œ ์„ค๋ช… ์ถ”๊ฐ€ ๊ฐ€๋Šฅ

 

 

5. @ApiModelProperty

@ApiModelProperty(
	name = "id"
	, example = "example1"
)
  • Dto Field ์˜ˆ์ œ ์„ค๋ช…
  • @ApiModelProperty Annotation์„ ์‚ฌ์šฉํ•˜๋Š” DTO Class Field์— ์ถ”๊ฐ€ํ•˜๋ฉด, ํ•ด๋‹น DTO Field์˜ ์˜ˆ์ œ Data ์ถ”๊ฐ€ ๊ฐ€๋Šฅ

 

 

6. @ApiIgnore

@ApiIgnore
  • Swagger UI ์ƒ ๋ฌด์‹œ (์ œ์™ธ)

 

 

 

 

Contents

ํฌ์ŠคํŒ… ์ฃผ์†Œ๋ฅผ ๋ณต์‚ฌํ–ˆ์Šต๋‹ˆ๋‹ค. ๐Ÿ˜Š

์ด ๊ธ€์ด ๋„์›€์ด ๋˜์—ˆ๋‹ค๋ฉด ๊ณต๊ฐ ๋ถ€ํƒ๋“œ๋ฆฝ๋‹ˆ๋‹ค. ๐Ÿ‘