μ€λλ§μ ν¬μ€ν νλ μ΄μ λ νλμ λ³ ν μμ΄ νλ‘μ νΈλ₯Ό μ΄μ΄κ°κ³ μκΈ° λλ¬Έμ.. μλ‘κ² λ¬΄μΈκ°λ₯Ό μμκ°κ±°λ 볡μ΅νλ μΌμ΄ μ μμ΅λλ€..^^ μ€λμ Swaager μ¬μ© λμ€μ κΆκΈν μ μ΄ λ§μμ§λ©΄μ μ‘°μ¬ν λ΄μ©λ€μ μ 리ν λ΄μ©μ ν¬μ€ν ν΄λ³΄λ € ν©λλ€.
Swagger λ±μ₯ μ κ³Ό ν μ°¨μ΄λ?
Swaggerκ° μΈμμ λ±μ₯νκΈ° μ , κ°λ°μ κ° μν΅ λ°©μμ λ¨μνκ² λ°±μλ κ°λ°μκ° URL λ° Request, Responseλ₯Ό μ§μ λ¬Έμνν΄μ νλ‘ νΈμλ κ°λ°μμκ² μ λ¬νλ λ°©μμ μ¬μ©νμ΅λλ€.
λ°λΌμ κΈ°λ₯ ꡬνμ μν API λͺ μΈ λ° μꡬμ¬νμ΄ μλ€κ³ κ°μ νμ λ, κ° κ°λ°μ κ°μ νμ°μ μΈ μ± μμ΄ λ°λ¦ λλ€.
- λ°±μλ κ°λ°μλ API ꡬνμ μμ΄μ μ΄λ ν μ€μκ° μμ΄μΌ ν©λλ€.
- λ°±μλ κ°λ°μλ κΈ°λ₯ μꡬμ¬νμ μλ²½ν μ΄ν΄ν΄μΌ ν©λλ€.
- νλ‘ νΈμλ κ°λ°μλ κΈ°λ₯ ꡬνμ μμ΄μ μ΄λ ν μ€μκ° μμ΄μΌ ν©λλ€.
- νλ‘ νΈμλ κ°λ°μλ κΈ°λ₯ μꡬμ¬νμ μλ²½ν μ΄ν΄ν΄μΌ ν©λλ€.
λ¨μν λ°λ³΅ μμ μΈ λ§νΌ μμ°μ± μΈ‘λ©΄μμλ λ€μ λΉν¨μ¨μ μ λλ€. μ΄λ‘ μΈν΄ μ¬λ¬ λ°©λ©΄μΌλ‘ λΆνΈν¨μ΄ μΌκΈ°λ©λλ€.
- λ°±μλ κ°λ°μκ° API λ¬Έμλ₯Ό μΌμΌμ΄ μμ±νλ λ²κ±°λ‘μ
- APIκ° λ³κ²½λλ©΄μ λΉμΌκ΄μ μΈ λ¬Έμλ₯Ό λ€μ μμ ν΄μΌ νλ λ²κ±°λ‘μ
- μκΈ° μμ±μΌλ‘ μΈν ν΄λ¨Όμλ¬ λ°μμΌλ‘ κ°λ°μ κ°μ μμ¬μν΅μ΄ μ΄λ €μ
- νλ‘ νΈμλ κ°λ°μκ° Postman, cURLλ‘ μ§μ URL λ° Request μμ±νμ¬ APIλ₯Ό ν μ€νΈν΄μΌ νλ λ²κ±°λ‘μ
μμ κ°μ λ²κ±°λ‘μμ ν΄κ²°νκΈ° μν΄ λ±μ₯ν Swaggerλ OAS(Open Api Specification)λ₯Ό μν μ€νμμ€ νλ μμν¬μ λλ€. μ¬μ©νλ©΄ μ»μ μ μλ μ₯μ μ΄ μμ΅λλ€.
- API λ¬Έμλ₯Ό μμ±ν λ, κ°λ°μκ° λ¬Έμλ₯Ό μμ±νμ§ μμλ λλ―λ‘ κ°λ° μκ° λ¨μΆ
- Swagger UIλ₯Ό μ΄μ©νλ©΄ APIλ₯Ό μ½κ² ν μ€νΈν μ μμΌλ©°, API νΈμΆ μ μ λ¬ν΄μΌ ν νλΌλ―Έν°λ₯Ό νμΈν μ μμ
- Swaggerλ₯Ό μ¬μ©νλ©΄ API λ²μ κ΄λ¦¬κ° μ©μ΄ν΄μ§κ³ λ€μν API λ¬Έμλ₯Ό ν΅ν©ν μ μμ
- Spring Bootμμ Swaggerλ₯Ό μ¬μ©νλ©΄ API λ¬Έμλ₯Ό μμ±νλ λ° νμν μ½λλ₯Ό μ§μ μμ±νμ§ μμλ λλ―λ‘ κ°λ°μλ API κ°λ°μ μ§μ€ν μ μμ
Swaggerλ₯Ό λ€λ£¨λ λ κ°μ§ λ°©λ²
1) YAML
Swaggerλ₯Ό ꡬμ±νλ λ°©λ² μ€ μ²« λ²μ§Έλ YAMLνμΌμ μ¬μ©νκ² λλ€λ©΄ Swagger UIλ₯Ό μν μλ²λ₯Ό λ°λ‘ λκ³ , Swaggerμμ API μμ²μ νλ©΄ κ·Έ μμ²μ ν΄λΉ μλ²λ‘ μ λ¬νκ² λ©λλ€. λ°λ©΄ Spring Frameworkμμ κ΅¬μ± μ μλ² μμ²΄κ° Swagger κ²Έ λ°±μλ μλ²κ° λΌμ, μμ² λ° μλ΅μ μ²λ¦¬νκ² λ©λλ€.
μ΄λ¬ν ꡬ쑰λ₯Ό λ°λ₯΄λ©΄ YAML νμΌμ μ΄ν΄νκ³ μμ νκΈ° μ¬μμ§κ³ , λͺ νν μν€ν μ²λ₯Ό κ°μ§ μ μμ΄μ κ°λ°μλΏλ§ μλλΌ κΈ°νμλ μ½κ² μ΄ν΄ν μ μμ΅λλ€. YAML νμΌμ ν΅ν΄ ꡬμ±νλ λ°©λ²μ μΆμ² μκΈμ ν΅ν΄ μμΈν λ΄μ©μ νμΈν μ μμ΅λλ€.
2) Spring Frameworkμμ ꡬμ±
YAMLνμΌλ‘ ꡬμ±νλ κ²κ³Ό λ€λ₯΄κ² κ° Spring Framework νκ²½μμ λμνλ μλ² λ΄μ Swaggerλ₯Ό μ¬μ©ν¨μΌλ‘μ¨ κ° μλ²μ API λͺ μΈλ₯Ό νμΈν μ μλλ‘ κ΅¬μ±νλ λ°©λ²μ λλ€. μ€μ κ³Ό κ΄λ ¨λ μ΄λ Έν μ΄μ κ³Ό ν¨μλ€μ΄ μ λμμμ΄ μ μ©νλ λ°©λ²μ μ½μ§λ§, μ½λ λ΄μ μμ±μ νλ€ λ³΄λ μμ€ μ½λμ κ°λ μ±μ΄ μ νλλ€λ λ¨μ μ΄ μμ΅λλ€.
Swagger μ¬μ©μ λλ Tool & Library
1) Tool
1. Swagger Codegen
Codegenμ server stubs client SDKsλ₯Ό μμ±ν μ μκ² ν΄ μ€λλ€. μ¦, Swaggerμμ μ μν μ€κ³λλ‘ κ°λ°μ μ§νν μ μλλ‘ ν©λλ€. λͺ¨λ μΈμ΄λ₯Ό μ§μνκ³ μμ§λ μμ΅λλ€.
2. Swagger Editor
Swagger Editorλ Swaggerλ₯Ό μ¨λΌμΈμμ μμ±ν μ μλ κ²μ΄ νΉμ§μ λλ€. Cloud νκ²½μμ μμ ν μλ μκ³ , Editorλ₯Ό λ€μ΄λ‘λνμ¬μ μ¬μ©ν μλ μμ΅λλ€. Dockerλ₯Ό ν΅ν΄ μ΄λ―Έμ§λ‘ μ 곡νκ³ μμ΅λλ€.
3. Swagger UI
Swaggerμ νμ€μ λ§μΆ° UIλ₯Ό μμ±ν΄ μ£Όλ μλν°μ λλ€.
2) Library
Swaggerλ₯Ό Spring νκ²½μμ μ½κ² μ¬μ©ν μ μλλ‘ λμμ£Όλ λΌμ΄λΈλ¬λ¦¬κ° μμ΅λλ€.
1. Springfox
Springfox Swaggerμ κ²½μ° 3.00 λ²μ μ λ§μ§λ§μΌλ‘ μ λ°μ΄νΈκ° μ€λ¨λμ΄μ μ μ¬μ©νμ§ μλ μΆμΈλΌκ³ ν©λλ€. (Maven Repository κΈ°μ€ 2020λ 7μ λ§μ§λ§ μ λ°μ΄νΈ)
2. SpringDoc
SpringFoxμ κΈ°λ₯μ λμΌνμ§λ§ Spring WebFlux (λ Ό λΈλ‘νΉ λΉλκΈ° λ°©μμ μΉ κ°λ°)μ μ§μν©λλ€. λν, κ·Έλ£Ή κ° API μ λ ¬μ΄ κ°λ₯νλ€λ μ₯μ μ΄ μμ΅λλ€.
Springfox Swaggerμ κ²½μ° 2020λ 7μμ μ λ°μ΄νΈ μ΄ν νμ μ λ°μ΄νΈκ° μμ΅λλ€. μ΄ν λμ¨ κΈ°λ₯λ€μ λμμ΄ μ λλ κ²½μ°κ° μμ΄μ SpringDocλ₯Ό μμ£Ό μ¬μ©ν©λλ€. κ²λ€κ° SpringBoot 3 νκ²½μμ SpringFoxλ μ¬μ©μ΄ λΆκ°λ₯νλ€κ³ ν©λλ€.
Swagger μ¬μ© λ°©λ²
SpringBootμμ Swagger μ€μ νκΈ°
μ€μ μ μμ μ λ SpringBoot 3.0.3 λ²μ μμ μ μ©νμ΅λλ€. μλ μμ‘΄μ±μ μΆκ°νμ¬ Swaggerλ₯Ό μ¬μ©ν μ μλλ‘ ν΄μ€λλ€.
implementation 'org.springdoc:springdoc-openapi-starter-common:2.0.2'
μ μ€μ λ§μΌλ‘λ νμ¬ λ‘컬μμλ Swagger λ¬Έμκ° μμ±λ©λλ€.
http://localhost:8080/swagger/index.html
Swagger API λ¬Έμ κ΄λ ¨ μ€μ λ€μ μ μ΄ν μ μλλ‘ SwaggerConfig νμΌμ μΆκ°ν©λλ€.
@Configuration
public class SwaggerConfig {
private String version = "1.0.0";
@Bean
public OpenAPI openAPI() {
return new OpenAPI()
.components(new Components())
.info(apiInfo());
}
private Info apiInfo() {
return new Info()
.title("μ λͺ©")
.description("μ€λͺ
")
.version(version);
}
}
λν Swaggerλ₯Ό μ μ΄ν μ μλ yaml νμΌμ μΆκ°ν΄ μ€λλ€. packages-to-scan μμ±μ Swaggerλ₯Ό μ¬μ©νκΈ° μν Controllerκ° μλ ν¨ν€μ§ κ²½λ‘λ₯Ό μ§μ νλ©΄ μλμΌλ‘ Swagger λ¬Έμμ λ±λ‘λ©λλ€. λ±λ‘μ μμΉ μλ 컨νΈλ‘€λ¬μ @Hidden μ΄λ Έν μ΄μ μ μ¬μ©νμ¬ μ μΈν μ μμ΅λλ€. κ° μμ±μ λν΄μ λ μκ³ μΆμΌμλ©΄ 곡μ λ¬Έμλ₯Ό νμΈν΄ μ£ΌμΈμ. (https://springdoc.org/#properties)
springdoc:
packages-to-scan: com.example.swagger.web
default-consumes-media-type: application/json;charset=UTF-8
default-produces-media-type: application/json;charset=UTF-8
swagger-ui:
path: /
disable-swagger-default-url: true
display-request-duration: true
operations-sorter: alpha
μ΄μ Swagger λ¬Έμμ λ±λ‘ν Controller νμΌμ μμ ν΄μ Swagger λ¬Έμλ₯Ό λ±λ‘ν μ μμ΅λλ€. SpringBoot 3 λ²μ κ³Ό 2 λ²μ μμ μ΄λ Έν μ΄μ μ°¨μ΄κ° μμ΄ λ¨Όμ μ§κ³ λμ΄κ° λ³΄κ² μ΅λλ€.
@Api → @Tag
@ApiIgnore → @Parameter(hidden = true) or @Operation(hidden = true) or @Hidden
@ApiImplicitParam → @Parameter
@ApiImplicitParams → @Parameters
@ApiModel → @Schema
@ApiModelProperty(hidden = true) → @Schema(accessMode = READ_ONLY)
@ApiModelProperty → @Schema
@ApiOperation(value = "foo", notes = "bar") → @Operation(summary = "foo", description = "bar")
@ApiParam → @Parameter
@ApiResponse(code = 404, message = "foo") → @ApiResponse(responseCode = "404", description = "foo")
μλμ κ°μ΄ μμ APIλ₯Ό μμ±ν΄ 보μμ΅λλ€.
@GetMapping("/example/{id}")
@Operation(summary = "μ‘°ν μμ ", description = "μ‘°ννλ€", responses = {
@ApiResponse(responseCode = "200",
description = "μ‘°ν μ±κ³΅",
content = @Content(array = @ArraySchema(schema = @Schema(implementation = exampleResource.class))))
})
@Parameter(name = "id", description = "μμ νλΌλ―Έν°", in = ParameterIn.PATH)
public List<CafeResource> search(@PathVariable("id") Long id) {
...
}
@Hidden
@GetMapping("/hidden")
public String hidden() {
return "Swaggerμ λ±λ‘λμ§ μλ API";
}