1. Swagger 3.0 ์ธํ ํ๊ธฐ.
๊ตฌ๊ธ์ ๊ฒ์ํด์ ๋์จ ์ค์จ๊ฑฐ ์ธํ ๊ด๋ จ ํฌ์คํธ๋ ๋๋ถ๋ถ 2.X ๋ฒ์ ๋ ์ด๊ฑฐ๋, 3.0 ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋ฐ์์์๋, ์ค์จ๊ฑฐ ์ธํ ์์ SWAGGER2๋ฒ์ ์ผ๋ก ๋ฎ์ถ์ด ์ฌ์ฉํ๋ ๊ธ์ด ํผ์ฌํ์ฌ ์ ๋ฆฌํ๊ณ ์ ๊ธ์ ์์ฑํ๋ค.
์ฐ์ ๋ด๊ฐ ์ ์ฉํ๊ณ ์ ํ๋ ์คํ๋ง ๋ถํธ์ ๋ฒ์ ์ 2.7.1 ๋ฒ์ ์ด๋ฉฐ, ์ค์จ๊ฑฐ๋ open api 3.0 OAS3 ๋ฌธ์ ๋ฒ์ ์ ๋ง๋ค๊ณ ์ ํ๋ค.
- build.gradle
// https://mvnrepository.com/artifact/io.springfox/springfox-boot-starter
implementation group: 'io.springfox', name: 'springfox-boot-starter', version: '3.0.0'
// https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui
implementation group: 'io.springfox', name: 'springfox-swagger-ui', version: '3.0.0'
// https://mvnrepository.com/artifact/io.springfox/springfox-oas
implementation group: 'io.springfox', name: 'springfox-oas', version: '3.0.0'
์ 3๊ฐ์ง ๋ฒ์ ์ ๋ฐ์์ ์ฌ์ฉํ์ ๋, ์ ์ ๊ตฌ๋์ด ๊ฐ๋ฅ ํ๋ค. ๋ณดํต์ springfox-boot-starter๋ง ๋ฃ์ผ๋ฉด ๋๋ค๋ ์๊ธฐ๊ฐ ๋ง์๋๋ฐ, ๋ด ๊ฒฝ์ฐ์๋ ์๋ 2๊ฐ์ง๋ ์์ด์ผ ๊ตฌ๋์ด ์ ์์ ์ผ๋ก ๊ฐ๋ฅํ๋ค.
- SwaggerConfig.java
package com.sample.swagger.config;
import java.util.Arrays;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
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;
@EnableWebMvc
@Configuration
public class SwaggerConfig extends WebMvcConfigurationSupport {
@Bean
public Docket api(TypeResolver typeResolver) {
return new Docket(DocumentationType.OAS_30) // 3.0 ๋ฌธ์๋ฒ์ ์ผ๋ก ์ธํ
.useDefaultResponseMessages(true)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("com.sample.swagger.controller"))
.paths(PathSelectors.any())
.build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("Swagger 3.0 Api Sample")
.description("This is Sample")
.version("1.0")
.build();
}
}
์์ ์ค์ ์ ์น ์ค์ ์ ์ถ๊ฐํ๋ค. ์ฐธ๊ณ ๋ก, MVC์ค์ ์ ๋ฐ๋ก ํด์ฃผ์ง ์๋ ํ๋ก์ ํธ๋ผ๋ฉด ์๋์ ์ค์ ๋ ๊ฐ์ด ์ถ๊ฐํด์ฃผ์ด์ผ ํ๋ค.
- WebConfig.java
package com.sample.swagger.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/swagger-ui/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/springfox-swagger-ui/")
.resourceChain(false);
}
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/swagger-ui/")
.setViewName("forward:/swagger-ui/index.html");
}
}
์ ์ค์ ์ด ์๋ค๋ฉด, ์๋ฌด๋ฆฌ ํ๋ก์ ํธ๋ฅผ ๋๋ ค๋ ์ค์จ๊ฑฐ ํ์ฑ ํ์ด์ง์ ์ ๊ทผ ํ ์ ๊ฐ ์๋ค. (๋ฆฌ์์ค๊ฐ ์๋ค๊ณ ์๋ฌ๊ฐ ๋ฐ์ํ๋ค.)
2. @Schema ์์ฑ
Swagger 3.0 ๋ฒ์ ์์๋ ApiModelProperty ๋์ Schema ์ด๋
ธํ
์ด์
์ผ๋ก ๋ชจ๋ธ์ ์์ฑํ๋ค.
ํ๋ผ๋ฏธํฐ / ์ค์ ์๋ต ๋ฐ์ดํฐ / ์๋ต ๋ด ๋ฐ์ดํฐ 3๊ฐ์ง ์ข
๋ฅ์ ๋ํด ์์ ๋ฅผ ์ ๊ณตํ ์๊ฐ์ด๋ฏ๋ก, ์ธ๊ฐ๋ฅผ ๋ค ์ ์ํด์ผ ํ๋ค.
์์ ๊ตฌ์กฐ๋ dataParam / dataRes / data ๋ก ์ก์์ผ๋ฉฐ, dataRes ๋ด๋ถ์ List<data> ๊ฐ ์กด์ฌํ๋ ๊ฒ์ผ๋ก ์ธํ
ํ์๋ค.
@Schema
- name : ๋ชจ๋ธ๋ช
- description : ํด๋น ๋ชจ๋ธ์ ๋ํ ์ค๋ช
- defaultValue : ๊ธฐ๋ณธ ๊ฐ(์๋ค๋ฉด)
- allowableValues : ํ์ฉ ๊ฐ ๋ฒ์(์๋ค๋ฉด)
- example : ์์ ๋ฐ์ดํฐ (์์ฑํด์ผ ์ค์จ๊ฑฐ ๋ฌธ์์ ๋ฐ์ดํฐ๊ฐ ์ผ๋ฐ ํ์
์ด ์๋ ๋ฐ์ดํฐ๊ฐ ์๋ ๊ฒ์ผ๋ก ๋ํ๋จ)
- dataParam.java
package com.sample.swagger.data;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.Setter;
@Schema(name = "dataParam", description = "์ ์ ์กฐํ ํ๋ผ๋ฏธํฐ")
@Getter
@Setter
public class dataParam {
@Schema(description = "์์ฒญ ๊ฐ์", defaultValue = "", allowableValues = {}, example = "1")
private int num;
}
- data.java
package com.sample.swagger.data;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.Setter;
@Schema(name = "data", description = "์ ์ ๋ฐ์ดํฐ")
@Getter
@Setter
public class data {
@Schema(description = "์ ์ ๋ฒํธ", defaultValue = "", allowableValues = {}, example = "1")
private int userNo;
@Schema(description = "์ ์ ์ด๋ฆ", defaultValue = "", allowableValues = {}, example = "user1")
private String username;
}
- dataRes.java
package com.sample.swagger.data;
import java.util.List;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.Setter;
@Schema(name = "dataRes", description = "์ ์ ์กฐํ ์๋ต ๋ฐ์ดํฐ")
@Getter
@Setter
public class dataRes {
@Schema(description = "์ ์ ๋ฆฌ์คํธ", defaultValue = "", allowableValues = {}, example = "")
private List<data> dataList;
}
๊ทธ๋ฆฌ๊ณ , ์๋ต์ ์ ์ํ ํด๋์ค๋ ์์ฑํ์๋ค. ์ฌ๊ธฐ์ ์ฃผ๋ชฉํ ์ ์ ๊ธ๋ก๋ฒ ์๋ฌ ์ฒ๋ฆฌ ํน์ ๊ธฐํ ์๋ฌ ์ฒ๋ฆฌ๋ก ์ธํด ๋ฆฌํด๋๋ ๋ฐ์ดํฐ ํํ๋ ์ค์จ๊ฑฐ์์ ์ก์ง ๋ชปํ๋ค๋ ๊ฒ์ด๋ค. ๋ฐ๋ผ์, ๋ณ๋๋ก ์ถ๊ฐํ๊ณ ์ถ์ ์์ธ ์ผ์ด์ค์ ๊ฒฝ์ฐ(์๋ฅผ ๋ค์ด, 200 ์ ์ ๋ฆฌํด ์ธ, 400-500๋ ๋ฑ์ ์๋ฌ๋ฅผ ์ค์จ๊ฑฐ์์ ์ ๊ณตํ๊ณ ์ถ์ ๊ฒฝ์ฐ.) ๋ณ๋ ํด๋์ค๋ฅผ ์์ฑํ์ฌ @Schema ์ด๋ ธํ ์ด์ ์ ์ค ํ, ์๋ต์ ์ถ๊ฐํด์ฃผ์ด์ผ ํ๋ค.
์ฐ์ , ์๋ต ํด๋์ค 3๊ฐ์ง๋ฅผ ์์ฑํ๋ค.
- ApiRes : ์ ์ ์๋ต ์, ์ปจํธ๋กค๋ฌ์์ ๋ฆฌํดํ๋ ํด๋์ค
package com.sample.swagger.response;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.Setter;
@Schema(name = "ApiRes", description = "Api Response Format")
@Getter
@Setter
public class ApiRes<T> {
@Schema(description = "์์ฒญ๊ฒฐ๊ณผ ์ํ", nullable = false, example = "success")
private String result_status;
@Schema(description = "์์ฒญ๊ฒฐ๊ณผ", nullable = false, example = "")
private T result;
public ApiRes(T result) {
this.result_status = "success";
this.result = result;
}
}
- ApiErr : ์๋ฌ๊ฐ ๋ฐ์ํ ๊ฒฝ์ฐ ๋ณด์ฌ์ค ์๋ฌ
package com.sample.swagger.response;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.Setter;
@Schema(name = "ApiErr", description = "Api Response Err")
@Getter
@Setter
public class ApiErr {
@Schema(description = "์์ฒญ๊ฒฐ๊ณผ ์ํ", nullable = false, example = "fail")
private String error_status;
@Schema(description = "์์ฒญ๊ฒฐ๊ณผ ๋ฉ์ธ์ง", nullable = false, example = "์์ฒญ์ด ์คํจํ์์ต๋๋ค.")
private String error_message;
public ApiErr(String error_status, String error_message) {
this.error_status = error_status;
this.error_message = error_message;
}
}
- ApiNoAuth : ๊ถํ ์๋ ๊ฒฝ์ฐ ๋ณด์ฌ์ค ์๋ฌ
package com.sample.swagger.response;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.Setter;
@Schema(name = "ApiNoAuth", description = "Api Response No Auth")
@Getter
@Setter
public class ApiNoAuth {
@Schema(description = "์์ฒญ๊ฒฐ๊ณผ ์ํ", nullable = false, example = "fail")
private String error_status;
@Schema(description = "์์ฒญ๊ฒฐ๊ณผ ๋ฉ์ธ์ง", nullable = false, example = "๊ถํ์ด ์์ต๋๋ค.")
private String error_message;
}
๋ฐ์ดํฐ ๋ฐ ์๋ต์ ๋ํ ์คํค๋ง๋ฅผ ์์ฑํ์์ผ๋ฉด, ํด๋น ์ปจํธ๋กค๋ฌ๋ก ์ด๋ํ์ฌ ์ปจํธ๋กค๋ฌ์ ๋ํด ์ ์ํ๋ค.
3. @ApiResponse, @Tag, @ApiOperation
@Tag : ๊ฐ์ ํ๊ทธ๋ก ์์ฑ๋ ์ปจํธ๋กค๋ฌ๋ค์ ๋ฌถ์ด์ฃผ๋ ์ญํ ์ ํ๋ค.
- name : ํ๊ทธ๋ช
์์ฑ
- description : ํ๊ทธ์ ๋ํ ์ค๋ช
@ApiResponse : ํด๋น ์ปจํธ๋กค๋ฌ์ ๋ํ ์๋ต์ ์ ์ํ๋ค.
- ์์์ @ApiResponses(values={}) ๋ก ๋ฌถ์ธ๋ค.
- responseCode : ์๋ต์ฝ๋๋ฅผ ์ ์ํ๋ค.
- description : ํด๋น ์๋ต์ ๋ํ ์ค๋ช
์ ์ ์ํ๋ค.
- content : ํด๋น ์๋ต์ ๋ํ ๋ด์ฉ์ ์ ์ํ๋ค. @Content๋ฅผ ํตํด ๋ด์ฉ์ ๋ฐ๋ก ์ ์ํ ์ ์์ผ๋ฉฐ, ๋ณดํต @Schema implemention์ ํตํด ๋ฏธ๋ฆฌ ์ ์๋ ํด๋์ค ์คํค๋ง๋ฅผ ์ฌ์ฉ ๊ฐ๋ฅํ๋ค.
@ApiOperation: API ๋์์ ๋ํ ์ค๋ช
์ ์ ์ํ๋ค.
- value : ๋์ ๊ฐ์ ์ ์ํ๋ค.
- notes : ๋์์ ๋ํ ์ค๋ช
์ ์ ์ํ๋ค.
- authorizations : ๋ค์์ ์ธ๊ธํ ์ธ์ฆ ๊ด๋ จ ๊ฐ์ ์ ์ํ๋ค. (ํค ๊ด๋ จ)
- ApiController.java
package com.sample.swagger.controller;
import java.util.ArrayList;
import java.util.List;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.sample.swagger.data.data;
import com.sample.swagger.data.dataParam;
import com.sample.swagger.data.dataRes;
import com.sample.swagger.response.ApiErr;
import com.sample.swagger.response.ApiNoAuth;
import com.sample.swagger.response.ApiRes;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.Authorization;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
@Tag(name = "user", description = "get user list")
@RestController
@RequestMapping("/api")
public class ApiController {
@Tag(name = "user")
@ApiOperation(value = "์ ์ ๋ฆฌ์คํธ", notes = "ํ๋ผ๋ฏธํฐ๋ก ๋์ด์จ ์ ๋งํผ ์ ์ ๋ฅผ ๋ฆฌํดํ๋ค.", authorizations = {
@Authorization(value = "apiKey") })
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "์์ฒญ ์ฑ๊ณต", content = @Content(schema = @Schema(implementation = ApiRes.class))),
@ApiResponse(responseCode = "201", description = "500๊ณผ ๋์ผ"),
@ApiResponse(responseCode = "401", description = "๊ถํ ์์(ํค๋๋ฝ)", content = @Content(schema = @Schema(implementation = ApiNoAuth.class))),
@ApiResponse(responseCode = "403", description = "500๊ณผ ๋์ผ"),
@ApiResponse(responseCode = "404", description = "500๊ณผ ๋์ผ"),
@ApiResponse(responseCode = "500", description = "์์ฒญ ์คํจ", content = @Content(schema = @Schema(implementation = ApiErr.class)))
})
@GetMapping(value = "/getUser", produces = "application/json")
public ResponseEntity<ApiRes<dataRes>> getUser(@RequestParam int num) {
dataRes res = new dataRes();
List<data> result = new ArrayList<data>();
for (int i = 0; i < num; i++) {
data d = new data();
d.setUserNo(i);
d.setUsername("user" + i);
result.add(d);
}
res.setDataList(result);
return new ResponseEntity<ApiRes<dataRes>>(new ApiRes<dataRes>(res), HttpStatus.OK);
}
@Tag(name = "user")
@ApiOperation(value = "์ ์ ๋ฆฌ์คํธ", notes = "ํ๋ผ๋ฏธํฐ๋ก ๋์ด์จ ์ ๋งํผ ์ ์ ๋ฅผ ๋ฆฌํดํ๋ค.", authorizations = {
@Authorization(value = "apiKey") })
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "์์ฒญ ์ฑ๊ณต", content = @Content(schema = @Schema(implementation = ApiRes.class))),
@ApiResponse(responseCode = "201", description = "500๊ณผ ๋์ผ"),
@ApiResponse(responseCode = "401", description = "๊ถํ ์์(ํค๋๋ฝ)", content = @Content(schema = @Schema(implementation = ApiNoAuth.class))),
@ApiResponse(responseCode = "403", description = "500๊ณผ ๋์ผ"),
@ApiResponse(responseCode = "404", description = "500๊ณผ ๋์ผ"),
@ApiResponse(responseCode = "500", description = "์์ฒญ ์คํจ", content = @Content(schema = @Schema(implementation = ApiErr.class)))
})
@PostMapping(value = "/getUser", produces = "application/json")
public ResponseEntity<ApiRes<dataRes>> postUser(@RequestBody dataParam param) {
dataRes res = new dataRes();
List<data> result = new ArrayList<data>();
for (int i = 0; i < param.getNum(); i++) {
data d = new data();
d.setUserNo(i);
d.setUsername("user" + i);
result.add(d);
}
res.setDataList(result);
return new ResponseEntity<ApiRes<dataRes>>(new ApiRes<dataRes>(res), HttpStatus.OK);
}
}
์๋ต์ ์์ฑ๋ ํด๋์ค๋ฅผ ์ง์ ํ๊ณ ๋๋ ค๋ณด๋ฉด ๊ฐ๋ ์ค๋ฅ๋ก ์ฐพ์ง ๋ชปํ๋ค๋ ๋ฉ์ธ์ง๊ฐ ๋ฐ ์ ์๋๋ฐ ์ด๋ด๋๋ ์ค์ ์ชฝ์ ๊ฑด๋๋ ค์ ํด๋น ํด๋์ค๋ฅผ ์ถ๊ฐํด์ฃผ๋ฉด ๋๋ค.
์ถ์ธก์ผ๋ก๋ ์ค์ ์ปจํธ๋กค๋ฌ์์ ๋ฆฌํดํ๋ ํด๋์ค๊ฐ ์๋๊ธฐ ๋๋ฌธ์ ์ก์ง ๋ชปํ๋๊ฒ ์๋๊ฐ ํ๋ค.
- SwaggerConfig.java
@Bean
public Docket api(TypeResolver typeResolver) {
return new Docket(DocumentationType.OAS_30)
// * ์ค์ ์๋ฌ ์ฒ๋ฆฌ๋ก ๋ฆฌํดํ๋ ํด๋์ค๋ฅผ ๋ช
์ํ๊ณ ์ ํ ๋ ํด๋น ๋ชจ๋ธ์ ์ถ๊ฐํด์ค๋ค.
.additionalModels(
typeResolver.resolve(ApiRes.class),
typeResolver.resolve(ApiErr.class),
typeResolver.resolve(ApiNoAuth.class))
// * ์คํค๋ง ๋ฉค๋ฒ ๋ณ์ ์ค, Date ๊ด๋ จ ๋ณ์ ๋ฌธ์ ๋ก ์ธํด ์ค์ ์ถ๊ฐ
.directModelSubstitute(LocalDate.class, java.sql.Date.class)
.directModelSubstitute(LocalDateTime.class, java.util.Date.class)
.useDefaultResponseMessages(true)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("com.sample.swagger.controller"))
.paths(PathSelectors.any())
.build();
}
์ด๋ ๊ฒ ๊น์ง๋ง ์์ฑํ๊ณ ๋ก์ปฌ ๊ตฌ๋ํ ๋ค, http://localhost:8080/swagger-ui/index.html ์ ์ ์ํ๋ฉด ๋ค์๊ณผ ๊ฐ์ ํ๋ฉด์ ๋ง๋๋ณผ ์ ์๋ค.
4. ํค ๊ด๋ จ ์ค์
Swagger์์ ๊ฐ์ฅ ํฐ ํน์ง ์ค ํ๋๋ ํค ๊ด๋ จ ์ค์ ์ ์ ๊ณตํ๋ค๋ ๊ฒ์ด๋ค. ์ฐพ์๋ณด๋ฉด ์ค์ ํ ํฐ ๊ฐ ๋๋ ์ฒ๋ฆฌ๋๋ ๋ฐฉ์์ ๋ฐ๋ผ ๋ค๋ฅด๊ฒ ์ ์ฉํ๋ ๋ฐฉ๋ฒ์ด ์๋ค.
์ฐ์ ํ์ฌ ์ํ๋ก ์์ฑํ ํ๋ก์ ํธ์์๋ ๋จ์ํ ํค๋์ ํน์ ๊ฐ์ด ์๋์ง๋ฅผ ์ฒดํฌํ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ ๋จ์ํ๊ฒ ์งํํ๋ค. ์ค์ ์ ๋จ๊ฒจ๋์์ผ๋ ์ฐธ๊ณ ํ๋ฉด ๋๋ค.
- SwaggerConfig.java
package com.sample.swagger.config;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Arrays;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import com.fasterxml.classmate.TypeResolver;
import com.sample.swagger.response.ApiErr;
import com.sample.swagger.response.ApiNoAuth;
import com.sample.swagger.response.ApiRes;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.ApiKey;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
@EnableWebMvc
@Configuration
public class SwaggerConfig extends WebMvcConfigurationSupport {
@Bean
public Docket api(TypeResolver typeResolver) {
return new Docket(DocumentationType.OAS_30)
// * ์ค์ ์๋ฌ ์ฒ๋ฆฌ๋ก ๋ฆฌํดํ๋ ํด๋์ค๋ฅผ ๋ช
์ํ๊ณ ์ ํ ๋ ํด๋น ๋ชจ๋ธ์ ์ถ๊ฐํด์ค๋ค.
.additionalModels(
typeResolver.resolve(ApiRes.class),
typeResolver.resolve(ApiErr.class),
typeResolver.resolve(ApiNoAuth.class))
// * ์คํค๋ง ๋ฉค๋ฒ ๋ณ์ ์ค, Date ๊ด๋ จ ๋ณ์ ๋ฌธ์ ๋ก ์ธํด ์ค์ ์ถ๊ฐ
.directModelSubstitute(LocalDate.class, java.sql.Date.class)
.directModelSubstitute(LocalDateTime.class, java.util.Date.class)
.useDefaultResponseMessages(true)
.apiInfo(apiInfo())
// ์ธ์ฆ ํ ํฐ ๋ฐฉ์์ด ์์๋๋ง ์ฌ์ฉ.
// .securityContexts(Arrays.asList(securityContext()))
.securitySchemes(Arrays.asList(apiKey()))
.select()
.apis(RequestHandlerSelectors.basePackage("com.sample.swagger.controller"))
.paths(PathSelectors.any())
.build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("Swagger 3.0 Api Sample")
.description("This is Sample")
.version("1.0")
.build();
}
// ์ธ์ฆ ํ ํฐ ๋ฐฉ์์ด ์์๋๋ง ์ฌ์ฉ.
/*
* private SecurityContext securityContext() {
* return SecurityContext.builder()
* .securityReferences(defaultAuth())
* .build();
* }
*/
// ์ธ์ฆ ํ ํฐ ๋ฐฉ์์ด ์์๋๋ง ์ฌ์ฉ.
/*
* private List<SecurityReference> defaultAuth() {
* AuthorizationScope authorizationScope = new AuthorizationScope("global",
* "accessEverything");
* AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
* authorizationScopes[0] = authorizationScope;
* return Arrays.asList(new SecurityReference("Authorization",
* authorizationScopes));
* }
*/
private ApiKey apiKey() {
return new ApiKey("apiKey", "apiKey", "header");
}
}
์์์ ์ค์ํ ๋ถ๋ถ์ apiKey() ๋ถ๋ถ์ธ๋ฐ, ํ๋ผ๋ฏธํฐ ์์๋๋ก name, keyname, passAs ์ด๋ค. ์ด๋ฅผ ์ฐธ๊ณ ํ์ฌ ์์ฑํ๊ณ ์๋์ ๊ฐ์ด ์ปจํธ๋กค๋ฌ์ @ApiOperation ๋ถ๋ถ์ ๋ด๋ถ ์ต์ ์ผ๋ก ์ง์ ํ๋ฉด ๋๋ค
- ApiController.java
@ApiOperation(value = "์ ์ ๋ฆฌ์คํธ", notes = "ํ๋ผ๋ฏธํฐ๋ก ๋์ด์จ ์ ๋งํผ ์ ์ ๋ฅผ ๋ฆฌํดํ๋ค.", authorizations = {@Authorization(value = "apiKey") })
ํด๋น ์์ ์ ์๋ฃํ๊ณ ๋ค์ ํ๋ก์ ํธ๋ฅผ ๋๋ ค ํ์ธํด๋ณด๋ฉด ์๋์ ๊ฐ์ด ๋ฒํผ์ด ์ถ๊ฐ๋ ๊ฒ์ ๋ณผ ์ ์๋ค.
ํด๋น ๋ฒํผ์ ํด๋ฆญํ๋ฉด ์๋์ ๊ฐ์ด ํ์ ์ด ๋ฌ๋ค.
์ฌ๊ธฐ์ ๊ฐ์ ์ ๋ ฅ ํ, Authorize๋ฅผ ํด๋ฆญํ๋ฉด, ํด๋น ๊ฐ์ด ์ ์ฅ๋์ด ํ ์คํธ ์ ๊ฐ์ด ์ ๋ฌ ๋๋ค.
๋๊ฒ ๊ฐ๋จํ๊ฒ ํ๋ค๊ณ ์์ํ๋๋ฐ ์ ๋ฆฌํ๋๋ฐ ์๊ฐ๋ณด๋ค ์๊ฐ์ด ๋ง์ด ๊ฑธ๋ ธ๋ค. ๋ฌด์๋ณด๋ค ์คํ๋ง ๋ถํธ์์ ์ด๋ ธํ ์ด์ ์ผ๋ก ์์ ํ๋ ์์ ๊ฐ ๋ง์ด ์์ด์ ๊ทธ๋ ๊ธฐ๋ ํ๊ณ , ๋ฒ์ ์ ๋ฐ๋ผ ์ต์ ๊ฐ์ด๋ ์ด๋ ธํ ์ด์ ์ด ๋ฌ๋ผ์ง๋ ๋ถ๋ถ๋ ์๋๋ฐ ์ฐพ๊ธฐ๊ฐ ๋งค์ฐ ํ๋ค์๋ค.
Swagger๋ ์ด๋ ๊ฒ ํ ๋ฒ ์ ๋ฆฌ ํด๋์ผ๋ฉด ํธํ๊ฒ ์ฌ์ฉํ ์ ์์ผ๋ ํ ๋ฒ ์ฏค์ ์๋ํด๋ณผ ๋ง ํ ๊ฐ์น๊ฐ ์๋ค๊ณ ๋ณธ๋ค.
ํด๋น ํฌ์คํธ์ ์์ ์์ค๋ ์๋์์ ๋ณด์ค ์ ์์ต๋๋ค.
https://github.com/Chiptune93/spring-example/tree/main/Swagger/3.0/swagger
GitHub - Chiptune93/spring-example: Spring Example
Spring Example. Contribute to Chiptune93/spring-example development by creating an account on GitHub.
github.com
'๐ฎSpring' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[SpringBoot] H2 Database CSV ๋ฐ์ดํฐ Import ํ๊ธฐ (0) | 2022.07.29 |
---|---|
[SpringBoot] Rest Api Sample ๋ง๋ค๊ธฐ #2 (0) | 2022.07.05 |
[SpringBoot] Rest Api Sample ๋ง๋ค๊ธฐ #1 (0) | 2022.07.05 |
[SpringBoot] CORS ์ฒ๋ฆฌํ๊ธฐ (0) | 2022.06.28 |
[AOP] AOP Aspect ๋ฅผ ์ด์ฉํ ๋ก๊ทธ ์ฒ๋ฆฌ ํ๊ธฐ (0) | 2022.04.18 |
๋๊ธ