모각소(2024)springdoc을 사용한 API 명세 자동관리

LEEHYUNJE·2024년 8월 24일
0

아주대학교_모각소!

목록 보기
22/23

나날이 늘어나는 API명세를 이제는 조금 관리하고, 프론트엔드 입장에서 보기도 편하도록 설정해야겠다고 마음을 먹었다. 그래야 프로젝트 개발 속도도 빨라질테니..

그래서 오늘은 springdoc 라이브러리를 활용한 OpenApi 명세 활용방법을 설명하도록 하겠다.

1. Build.Gradle에 라이브러리 등록

	implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.0.4'
   

2. SwaggerConfig 등록


@OpenAPIDefinition(
        info = @Info(title = "투개더 API 명세서",
                description = "COMP322-team12 투개더 API 명세서",
                version = "v1"))
@RequiredArgsConstructor
@Configuration
public class SwaggerConfig {
    @Bean
    public GroupedOpenApi chatOpenApi() {
        // "/v1/**" 경로에 매칭되는 API를 그룹화하여 문서화한다.
        String[] paths = {"/v1/**"};

        return GroupedOpenApi.builder()
                .group("투개더 API v1")  // 그룹 이름을 설정한다.
                .pathsToMatch(paths)     // 그룹에 속하는 경로 패턴을 지정한다.
                .build();
    }
}
  • @OpenAPIDefinition :
    이 어노테이션은 OpenAPI 3.0 명세를 정의하는 데 사용한다.
  • info 속성을 통해 API의 제목, 설명, 버전을 설정할 수 있다.
  • 설정된 내용은 Swagger UI나 OpenAPI 명세서에서 기본 정보로 표시된다.
  • title = "투개더 API 명세서": API 문서의 제목을 "투개더 API 명세서"로 설정한다.
  • description = "COMP322-team12 투개더 API 명세서": API 문서의 설명을 "COMP322-team12 투개더 API 명세서"로 설정한다.
  • version = "v1": API 문서의 버전을 "v1"으로 설정한다.
  • @chatOpenApi :
  1. 이 메소드를 통해 @Bean 어노테이션으로 정의된 스프링 Bean을 생성한다.
  2. 이 Bean은 GroupedOpenApi 객체를 반환한다.
  3. GroupedOpenApi는 Swagger에서 API를 그룹화하여 문서화할 수 있게 해준다.
  • paths = {"/v1/~"}: 이 배열은 "/v1/"로 시작하는 모든 경로에 대해 API를 문서화하도록 지정합니다. 경로 패턴은 정규식 형태로 설정할 수 있다.

  • group("투개더 API v1"): 이 메소드는 해당 그룹의 이름을 "투개더 API v1"으로 지정한다.

  • pathsToMatch(paths): 이 메소드는 지정된 경로 패턴에 매칭되는 API들을 그룹에 포함시킨다.

  • build(): GroupedOpenApi 객체를 빌드하여 반환한다.

결과

{
  "openapi": "3.0.1",
  "info": {
    "title": "투개더 API 명세서",
    "description": "COMP322-team12 투개더 API 명세서",
    "version": "v1"
  },
  "servers": [
    {
      "url": "http://localhost:8080",
      "description": "Generated server url"
    }
  ],
  "paths": {
    "/api/order/registration": {
      "post": {
        "tags": [
          "order-controller"
        ],
        "operationId": "orderRegistration",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RequestOrderDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrderDto"
                }
              }
            }
          }
        }
      }
    },
    "/api/item/new": {
      "post": {
        "tags": [
          "item-controller"
        ],
        "operationId": "ItemRegistration",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RequestItemFormDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResponseItemFormDto"
                }
              }
            }
          }
        }
      }
    },
    "/api/orders": {
      "get": {
        "tags": [
          "order-controller"
        ],
        "operationId": "ordersV3_page",
        "parameters": [
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int32",
              "default": 0
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int32",
              "default": 100
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/OrderDto"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/item/search/{id}": {
      "get": {
        "tags": [
          "item-controller"
        ],
        "operationId": "ItemSelection",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResponseItemFormDto"
                }
              }
            }
          }
        }
      }
    },
    "/api/item/search/all": {
      "get": {
        "tags": [
          "item-controller"
        ],
        "operationId": "ItemSelection_1",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ResponseItemFormDto"
                  }
                }
              }
            }
          }
        }
      }
    }
  }

ui로는 더 쉽게 확인할 수 있다. 하지만, 프론트엔드에게 전달하기 위해서는(서버를 열지 않았기 때문에) 위와같은 명세서로 전달할 예정이다.

남은 여러 기능들도 한번 이 명세와 함께 가보도록하자.


모각소 후기

창업동아리 blueprint는 모각소로 끝나는 것이 아니기때문에 개발한 api 를 프론트엔드, 백엔드가 서로 소통하기 위해서 오늘은 swagger에 대해서 공부해봤다. 창업동아리의 이커머스 플랫폼, 자기주도프로젝트를 통한 앱웹 개발 등을 2학기에 진행해야하는데 그때 오늘 공부한 내용을 좋게 쓸 수 있을 것 같아서 보람찼다. 이제 마지막 한번남은 모각소가 있는데 그 과정도 잘 끝내보도록하자.

profile
현재진행중

0개의 댓글