Skip to content

Commit

Permalink
๐Ÿ“ Swagger ์ ์šฉ ๋ฌธ์„œ ์ •๋ฆฌ(#16)
Browse files Browse the repository at this point in the history
  • Loading branch information
jun108059 committed Jul 29, 2022
1 parent ad5ffe3 commit 939376d
Showing 1 changed file with 141 additions and 0 deletions.
141 changes: 141 additions & 0 deletions docs/04_Swagger.md
@@ -0,0 +1,141 @@
# Swagger ์ ์šฉ

> ์ „์ฒด ์ฝ”๋“œ ์ ์šฉ ๊ณผ์ •์€ [github issue](https://github.com/jun108059/chat-server/issues/16) ์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
- springdoc ๊ณผ springfox ๋น„๊ต
- [springdoc ๊ณต์‹๋ฌธ์„œ](https://springdoc.org/)๋ฅผ ์ฐธ๊ณ ํ•ด์„œ ์ž‘์„ฑ
- ์ž‘์„ฑ์ผ(22.07.30) ๊ธฐ์ค€ ์ตœ์‹ ๋ฒ„์ „ : springdoc-openapi v1.6.9

## 1. springdoc vs springfox

> ๋‘ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋ชจ๋‘ Spring Framework๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ํ”„๋กœ์ ํŠธ์—์„œ Swagger๋ฅผ ์ด์šฉํ•ด API ๋ฌธ์„œ๋ฅผ ์‰ฝ๊ฒŒ ์“ธ ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ฃผ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ
- 2012 ~ 2015 : `Swagger SpringMVC` ์ด๋ฆ„์œผ๋กœ springfox ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ๋งŽ์ด ์‚ฌ์šฉ ๋จ
- 2015 ~ 2018 : `springfox-swagger` ์—…๋ฐ์ดํŠธ๊ฐ€ ํ™œ๋ฐœํžˆ ์ด๋ฃจ์–ด์ง
- 2018 ~ 2020 : fox ์—…๋ฐ์ดํŠธ๊ฐ€ ์ง„ํ–‰๋˜์ง€ ์•Š์•„ `springdoc` ๋“ฑ์žฅ, ๊ฐ•์„ธ
- 2020 ~ ํ˜„์žฌ : `springfox`๋„ ๋‹ค์‹œ ์—…๋ฐ์ดํŠธ ์‹œ์ž‘ํ•˜์—ฌ `springdoc` ๋น„์Šทํ•˜๊ฒŒ ํ™œ์šฉ ์ค‘

<img width="1166" alt="image" src="https://user-images.githubusercontent.com/42997924/181807257-846fbe25-4d5e-4a2a-b4fb-683fc9068d09.png">

(์ถœ์ฒ˜ : [Google Trends](https://trends.google.com/trends/explore?date=2019-06-10%202022-07-30&q=springfox,springdoc))

### 1-1. springdoc ์„ ํƒ

ํ”„๋กœ์ ํŠธ์—๋Š” `springdoc`์„ ์„ ํƒํ–ˆ๋‹ค. ๊ณต์‹๋ฌธ์„œ๊ฐ€ ์ฝ๊ธฐ ํŽธํ–ˆ๊ณ , API ๊ทธ๋ฃนํ•‘ ์„ค์ •์ด ๊ฐ„๋‹จํ–ˆ๋‹ค.

์ž‘์„ฑ์ผ ๊ธฐ์ค€ ๋” ํ™œ๋ฐœํžˆ ์—…๋ฐ์ดํŠธ ๋˜๊ณ  ์žˆ๊ธฐ๋„ ํ–ˆ๋‹ค.

## Swagger OpenAPI 3.0

- ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ OpenAPI 3.0 ์ŠคํŽ™์— ๋งž๋Š” JSON์„ ์ž๋™์œผ๋กœ ๋งŒ๋“ค์–ด ์ฃผ๋ฉด, Swagger UI๋Š” ๋งŒ๋“ค์–ด์ง„ JSON์„ ํ™”๋ฉด์— ํ‘œ์‹œ ํ•ด์ค€๋‹ค.

![image](https://user-images.githubusercontent.com/42997924/181805315-d8f1abd3-c661-4e78-8ec3-f953f095b563.png)

(์ถœ์ฒ˜ : [springdoc ๊ณต์‹๋ฌธ์„œ](https://springdoc.org/))

`springdoc-openapi-ui`๋ฅผ ์‚ดํŽด๋ณด๋ฉด swagger-ui๋ฅผ ํฌํ•จํ•˜๊ณ  ์žˆ๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

- `swagger-ui` : ํ•ต์‹ฌ ๋กœ์ง ๊ตฌํ˜„
- `springdoc-openapi` : swagger-ui๋ฅผ ์ถ”์ƒํ™”ํ•ด์„œ ๋” ์ž˜ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ

## 2. ํ”„๋กœ์ ํŠธ์— ์ ์šฉ

Gradle, yml ๊ธฐ๋ฐ˜์œผ๋กœ ์ ์šฉํ–ˆ๋‹ค.

### 2-1. dependency ์ถ”๊ฐ€

```groovy
// build.gradle ํŒŒ์ผ
dependencies {
implementation 'org.springdoc:springdoc-openapi-ui:1.6.9'
}
```

### 2-2. yml ์„ค์ • ์ถ”๊ฐ€

```yaml
springdoc:
swagger-ui:
path: /swagger-ui.html
groups-order: DESC
operationsSorter: method
disable-swagger-default-url: true
display-request-duration: true
api-docs:
path: /api-docs
show-actuator: true
default-consumes-media-type: application/json
default-produces-media-type: application/json
paths-to-match:
- /v1/**
```

### 2-3. SwaggerConfig ์„ค์ • ๋“ฑ๋ก

```java
// SwaggerConfig.java
@OpenAPIDefinition(
info = @Info(title = "์ฑ„ํŒ…์„œ๋น„์Šค API ๋ช…์„ธ์„œ",
description = "ํ—ฅ์‚ฌ๊ณ ๋‚  ์•„ํ‚คํ…์ฒ˜ ๊ธฐ๋ฐ˜ ์ฑ„ํŒ… ์„œ๋น„์Šค API ๋ช…์„ธ์„œ",
version = "v1"))
@RequiredArgsConstructor
@Configuration
public class SwaggerConfig {

@Bean
public GroupedOpenApi chatOpenApi() {
String[] paths = {"/v1/**"};

return GroupedOpenApi.builder()
.group("์ฑ„ํŒ…์„œ๋น„์Šค API v1")
.pathsToMatch(paths)
.build();
}
}
```

> ์ดํ›„์— JWT ํ† ํฐ ๊ด€๋ จ ์ •๋ณด๋„ ์—ฌ๊ธฐ์— ์ถ”๊ฐ€ํ•ด์ฃผ๋ฉด ์ข‹๋‹ค.
### 2-4. ์ปจํŠธ๋กค๋Ÿฌ์— ์ ์šฉ

```java
// DeleteMemberController.java
@RestController
@RequiredArgsConstructor
public class DeleteMemberController {

@Operation(summary = "ํšŒ์› ํƒˆํ‡ด ์š”์ฒญ", description = "ํšŒ์› ์ •๋ณด๊ฐ€ ์‚ญ์ œ๋ฉ๋‹ˆ๋‹ค.", tags = { "Member Controller" })
@ApiResponses({
@ApiResponse(responseCode = "200", description = "OK",
content = @Content(schema = @Schema(implementation = DeleteMemberResponse.class))),
@ApiResponse(responseCode = "400", description = "BAD REQUEST"),
@ApiResponse(responseCode = "404", description = "NOT FOUND"),
@ApiResponse(responseCode = "500", description = "INTERNAL SERVER ERROR")
})
@DeleteMapping("/v1/member/{id}")
ResponseEntity<DeleteMemberResponse> deleteMember(
@Parameter(description = "ํšŒ์› ID", required = true, example = "1") @PathVariable("id") Long id) {
// ์ƒ๋žต..
}
}
```

## 3. ๋„์›Œ์„œ ํ™•์ธ

์ ‘๊ทผ URL : http://localhost:8080/swagger-ui.html

<img width="1297" alt="image" src="https://user-images.githubusercontent.com/42997924/181805001-585b27dd-6c56-43db-a70c-1c0d3fc591e6.png">

## 4. ์ •๋ฆฌ

Code Base ์— Swagger ๊ด€๋ จ ์ฝ”๋“œ๊ฐ€ ๋งŽ์ด ๋“ค์–ด๊ฐ€๊ฒŒ ๋˜๋Š” ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด TDD์— ๋” ์ต์ˆ™ํ•ด์ง€๋ฉด RestDoc์œผ๋กœ ๋ณ€๊ฒฝํ•ด๋ณด๋ ค๊ณ  ํ•œ๋‹ค.

์ตœ๊ทผ์— ์Šคํ„ฐ๋””ํ•˜๋ฉด์„œ ๊ด€๋ จ ๋‚ด์šฉ์„ ๋…ผ์˜ํ•œ ์ ์ด ์žˆ๋Š”๋ฐ, ์–ด๋–ค ๋ถ„์ด ์ปจํŠธ๋กค๋Ÿฌ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋งŒ๋“ค์–ด์„œ Swagger ๊ด€๋ จ ๋‚ด์šฉ์„ ์ธํ„ฐํŽ˜์ด์Šค์— ์ž‘์„ฑํ•œ ๊ฒƒ์„ ๋ดค๋Š”๋ฐ ๊ทธ๊ฒƒ๋„ ์ข‹์€ ๋ฐฉ๋ฒ•์ธ ๊ฒƒ ๊ฐ™๋‹ค!

๋ฆฌํŽ™ํ„ฐ๋งํ• ๋•Œ ํ•œ๋ฒˆ ์ ์šฉํ•ด๋ณด๋ฉด ์ข‹์„ ๊ฒƒ ๊ฐ™๋‹ค.

**Reference**

- [springdoc ๊ณต์‹๋ฌธ์„œ](https://springdoc.org/)
- [springfox-swagger ๊ณต์‹๋ฌธ์„œ](http://springfox.github.io/springfox/docs/current/)

0 comments on commit 939376d

Please sign in to comment.