[Spring] Swagger ๐Ÿ‘‹

ํ™์ค€ยท2022๋…„ 1์›” 10์ผ
7
post-thumbnail

๋“ค์–ด๊ฐ€๋ฉฐ

์ด๋ฒˆ์— 1์ธ ํ† ์ด ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ ํ•ด๋ณด๋ ค๊ณ  ํ•œ๋‹ค.
๋ฐฑ์—”๋“œ๋Š” REST API ์„ค๊ณ„ ๋ฐ ๋ฌธ์„œํ™” ๋“ฑ์— ์œ ์šฉํ•˜๊ฒŒ ์‚ฌ์šฉ๋˜๋Š” Swagger๋ฅผ ์ด์šฉํ•˜์—ฌ ๋งŒ๋“ค์–ด๋ณด๋ ค๊ณ  ํ•œ๋‹ค.

์Šค์›จ๊ฑฐ(Swagger) ๋Š” Open Api Specification(OAS)๋ฅผ ์œ„ํ•œ ํ”„๋ ˆ์ž„์›Œํฌ์ด๋‹ค.
์ฆ‰, ๊ฐ„๋‹จํžˆ ๋งํ•ด API ์ŠคํŽ™์„ ๋ช…์„ธ, ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ํ”„๋กœ์ ํŠธ/๋ฌธ์„œ๋ผ๊ณ  ์ •์˜ํ•  ์ˆ˜ ์žˆ๋‹ค.


์„ ํƒ์ด์œ 

์ง„ํ–‰ํ•˜๋ ค๋Š” ํ† ์ดํ”„๋กœ์ ํŠธ๋Š” ๊ฐœ์ธ ํ”„๋กœ์ ํŠธ์ด๋‹ค ๋ณด๋‹ˆ ๋””์ž์ธ๋„ ๊น”๋”ํ•˜๊ฒŒ ์•ˆ ๋‚˜์˜ค๊ณ , ๋ฌธ์„œํ™”์— ์‹œ๊ฐ„์„ ๋งŽ์ด ์“ฐ๊ณ  ์‹ถ์ง€ ์•Š์•˜๋‹ค.์ด๋ ‡๊ฒŒ ๊ท€์ฐฎ์€ ์ผ์€ ์ž๋™ํ™” ์‹œํ‚ค๋Š” ๊ฒŒ ํ›Œ๋ฅญํ•œ ๋ฐฉ๋ฒ•์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜๋Š”๋ฐ ์ด๋ฅผ ์œ„ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ Swagger๋ผ ์ƒ๊ฐ๋“ค์–ด ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค.

Swagger ์žฅ์ 

  • ์ ์šฉํ•˜๊ธฐ ์‰ฝ๋‹ค.
  • API ์ •๋ณด ํ˜„ํ™ฉํ™” ๊ฐ€๋Šฅํ•˜๋‹ค.
  • ํ…Œ์ŠคํŠธํ•  ์ˆ˜ ์žˆ๋Š” UI๋ฅผ ์ œ๊ณตํ•œ๋‹ค.

์•„ํ‚คํ…์ฒ˜


Swagger ์‚ฌ์šฉ๋ฒ•

1. Swagger ์˜์กด์„ฑ ์ถ”๊ฐ€

Swagger ์‚ฌ์šฉ์„ ์œ„ํ•ด pom.xml์— ํ•ด๋‹น ์˜์กด์„ฑ ์ถ”๊ฐ€ ํ•ด์•ผํ•œ๋‹ค.

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

2. config ์„ธํŒ…

swagger ์„ค์ •์„ ์œ„ํ•ด SwaggerConfig ํด๋ž˜์Šค๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.

@EnableSwagger2
@Configuration
public class SwaggerConfig {
	
	  @Bean
	  public Docket api(){
	        return new Docket(DocumentationType.SWAGGER_2)
	        	  .useDefaultResponseMessages(false)  
	                  .select()
	                  .apiInfo(getApiInfo())         
	                  .apis(RequestHandlerSelectors.basePackage("com")) 
	                  .paths(PathSelectors.any()) 
	                  .build();                   
	  }
	

	  private ArrayList<ResponseMessage> getArrayList() {
	        ArrayList<ResponseMessage> lists = new ArrayList<ResponseMessage>();
	        lists.add(new ResponseMessageBuilder().code(500).message("500Error").build());
	        lists.add(new ResponseMessageBuilder().code(403).message("403Error").build());
	        lists.add(new ResponseMessageBuilder().code(401).message("401rror").build());
	        return lists;
	    }
	  
	  
	   public ApiInfo getApiInfo() {
	        return new ApiInfo(
	        	"Service REST API Documentation",        
	                "REST Api Documentation",            
	                "1.0",                              
	                "localhost:8080",
	                new Contact("hongjun","","hongjun@velog.com"), 
	                "Apache 2.0", "http://www.apache.org/licenses/LICENSE-2.0",
	                new ArrayList<VendorExtension>());
	    }

}
  • @EnableSwagger2
  • Swagger2 ๋ฒ„์ „์„ ํ™œ์„ฑํ™” ํ•˜๊ฒ ๋‹ค๋Š” ์–ด๋…ธํ…Œ์ด์…˜์ด๋‹ค.
  • Docket
  • Swagger ์„ค์ •์˜ ํ•ต์‹ฌ์ด ๋˜๋Š” Bean์ด๋‹ค.
    • useDefaultResponseMessages()
      false๋กœ ์„ค์ •ํ•˜๋ฉด, swagger์—์„œ ์ œ๊ณตํ•ด์ฃผ๋Š” ์‘๋‹ต์ฝ”๋“œ (200,401,403,404)์— ๋Œ€ํ•œ ๊ธฐ๋ณธ ๋ฉ”์‹œ์ง€๋ฅผ ์ œ๊ฑฐํ•ด์ค€๋‹ค.
    • select()
      ApiSelectorBuilder๋ฅผ ์ƒ์„ฑํ•˜์—ฌ apis()์™€ paths()๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค€๋‹ค.
    • apiInfo()
      ์ œ๋ชฉ, ์„ค๋ช… ๋“ฑ ๋ฌธ์„œ์— ๋Œ€ํ•œ ์ •๋ณด๋“ค์„ ์„ค์ •ํ•˜๊ธฐ ์œ„ํ•ด ํ˜ธ์ถœํ•œ๋‹ค.
    • apis()
      api ์ŠคํŽ™์ด ์ž‘์„ฑ๋˜์–ด ์žˆ๋Š” ํŒจํ‚ค์ง€๋ฅผ ์ง€์ •ํ•œ๋‹ค.
    • paths()
      apis()๋กœ ์„ ํƒ๋˜์–ด์ง„ API์ค‘ ํŠน์ • path ์กฐ๊ฑด์— ๋งž๋Š” API๋“ค์„ ๋‹ค์‹œ ํ•„ํ„ฐ๋งํ•˜์—ฌ ๋ฌธ์„œํ™”ํ•œ๋‹ค.
      PathSelectors.any()๋กœ ์„ค์ •ํ•˜๋ฉด ํŒจํ‚ค์ง€ ์•ˆ์— ๋ชจ๋“  API๋ฅผ ํ•œ ๋ฒˆ์— ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

๐Ÿ’ก ์ž์„ธํ•œ Docket Bean์„ ์„ค์ • ๋ฐฉ๋ฒ• ๋ฐ ์„ค๋ช…์€ ์—ฌ๊ธฐ๋ฅผ ์ฐธ๊ณ ํ•˜๋ฉด ๋œ๋‹ค.

3. Controller ์„ค์ •


import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;

@Api(value = "SwaggerController")
@RequestMapping("/v1/api")
@RestController
public class SwaggerController {

    @ApiOperation(value = "this is test!", notes = "note!!!!!")
    @GetMapping(value = "/board")
    public Map<String, String> selectOneBoard(@ApiParam(name = "first param", value = "first value", required = true) String input) {
        Map<String, String> result = new HashMap<>();
        result.put("author", "hongjun");
        result.put("content", "V1 API ๋‚ด์šฉ");
        return result;
    }
	
}
  • @Api
  • ํ•ด๋‹น ํด๋ž˜์Šค๊ฐ€ Swagger ๋ฆฌ์†Œ์Šค๋ผ๋Š” ๊ฒƒ์„ ๋ช…์‹œํ•ด์ค€๋‹ค.
    • value : ์‚ฌ์šฉ์ž ์ง€์ • ์ด๋ฆ„์„ ๋ถ™์ผ ์ˆ˜ ์žˆ๋‹ค. tags ์‚ฌ์šฉ์‹œ ๋ฌด์‹œ๋œ๋‹ค.
    • tags : ์‚ฌ์šฉํ•˜์—ฌ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ํƒœ๊ทธ๋ฅผ ์ •์˜ํ•  ์ˆ˜๋„ ์žˆ๋‹ค.
  • @ApiOperation
  • ํ•œ ๊ฐœ์˜ Operation์„ ์„ ์–ธํ•œ๋‹ค.
    • value : API์— ๋Œ€ํ•œ ์š”์•ฝ์„ ์ž‘์„ฑํ•œ๋‹ค. ์ œ๋Œ€๋กœ ํ‘œ์‹œ๋˜๋ ค๋ฉด 120์ž ์ดํ•˜์—ฌ์•ผ ํ•œ๋‹ค.
    • notes : API์— ๋Œ€ํ•œ ์ž์„ธํ•œ ์„ค๋ช…์„ ์ž‘์„ฑํ•œ๋‹ค.
  • @ApiParam
    • name : ํŒŒ๋ผ๋ฏธํ„ฐ ์ด๋ฆ„์„ ์ž‘์„ฑํ•œ๋‹ค.
    • value : ํŒŒ๋ผ๋ฏธํ„ฐ ์„ค๋ช…์„ ์ž‘์„ฑํ•œ๋‹ค.
    • required : ํ•„์ˆ˜ ํŒŒ๋ผ๋ฏธํ„ฐ์ด๋ฉด true, ์•„๋‹ˆ๋ฉด false๋ฅผ ์ž‘์„ฑํ•œ๋‹ค.

4. ์ ์šฉ ํ™”๋ฉด


๋งˆ๋ฌด๋ฆฌ

์—ฌ๊ธฐ๊นŒ์ง€ ๊ธฐ๋ณธ์ ์ธ Swagger๋ฅผ ์„ค์ •ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ์•„๋ณด์•˜๋‹ค.
๋‚ด๊ฐ€ ๊ฐœ๋ฐœ์„ ํ•œ ๊ฒƒ์„ ์‰ฝ๊ฒŒ ๋ฌธ์„œํ™” ํ• ์ˆ˜์žˆ๊ณ , ๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค์ด ์‰ฝ๊ฒŒ ์•Œ์•„๋ณผ ์ˆ˜ ์žˆ๋„๋ก ํ•œ๋‹ค๋Š” ์ ์—์„œ Swagger๋ฅผ ๋งŽ์ด ํ™œ์šฉํ•  ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒํ•œ๋‹ค ๐Ÿ‘€

profile
์–ด์ œ์˜ ๋‚˜๋ฅผ ์ด๊ธฐ์ž ๐Ÿ”ฅ

0๊ฐœ์˜ ๋Œ“๊ธ€