본문 바로가기
Spring Boot

SpringBoot를 활용한 Rest api 만들기(4) - Swagger Api 문서 자동화 설정하기

by ZIAHO 2023. 2. 27.

이전 포스팅에서는 H2 Database를 연동 해 보았습니다. 연동한 이후에 개발한 api를 테스트 해 보기 위해 Postman이라는 프로그램을 따로 설치 했었습니다.

 

Postman이라는 프로그램을 따로 설치하는 것이 다소 귀찮을 수 는 있지만 개발을 함에 있어서 유용하게 사용하는 프로그램이라고 하니 이번기회에 사용 해 보아서 많은 도움이 된 것 같다!

 

이번시간에는 Swagger라는 간단한 설정만으로도 api 테스트가 가능한 Web UI 문서 자동화 툴을 세팅해보겠습니다.

Swagger는 부가적인 서드파티 프로그램을 설치 할 필요가 없으며, 최소한의 작업을 통해 자동으로 API Document를 만들어주므로 클라이언트 개발자에게 문서 내용을 전달하기 위해 추가 작업을 하지 않아도 됩니다.


build.gradle에 swagger 라이브러리 추가하기

현재 시점에서는 더 최신버전의 swagger가 존재하지만 2.6.1 이상의 버전은 세팅이 잘 안되거나 Web UI가 기존 버전에 비해 매우 불편해졌으니 2.6.1버전을 사용하겠습니다.

 

SpringBoot 3버전 이상에서는 2.6.1 버전의 swagger를 사용 할 수 없음,

springfox swagger가 SpringBoot 3버전을 지원하지 않기 때문

 

대신 springdoc swagger를 사용할 수 있다. 적용방법은 아래에 후술하겠음.

implementation("io.springfox:springfox-swagger2:2.6.1")
implementation("io.springfox:springfox-swagger-ui:2.6.1")

해당 소스를 작성 한 이후에 인텔리제이 기준 단축키(Ctrl + Shifr + O)를 눌러서 라이브러리를 설치해주어야 한다.


SwaggerConfiguration 작성

org.ziaho.ziahorestapi 하위에 config package를 생성하고 SwaggerConfiguration 파일을 생성하겠습니다.

package org.ziaho.ziahorestapi.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

@Configuration
@EnableSwagger2
public class SwaggerConfiguration {

    @Bean
    public Docket swaggerApi() {
        return new Docket(DocumentationType.SWAGGER_2).apiInfo(swaggerInfo()).select()
                .apis(RequestHandlerSelectors.basePackage("org.ziaho.ziahorestapi.controller"))
                // basePackage : 지정한 pacakge 경로 하단의 Controller 내용을 읽어 매핑된 resource들을 문서화 시킵니다.
                .paths(PathSelectors.any())
                .build()
                .useDefaultResponseMessages(false); // 기본으로 세팅되는 200, 401, 403, 404 메세지를 표시 하지 않음
    }

    private ApiInfo swaggerInfo() {
        return new ApiInfoBuilder().title("Spring API Documentation")
                .description("앱 개발시 사용되는 서버 API에 대한 연동 문서입니다.")
                .license("zzziaho").licenseUrl("https://ziaho0403.tistory.com/").version("1").build();
    }

}

basePackage("org.ziaho.ziahorestapi.controller")).paths(PathSelectors.any())
org.ziaho.ziahorestapi 하위의 Controller 내용을 읽어 매핑된 리소스들을 문서화 시킵니다.

아래와 같이 작성해서 v1 으로 시작하는 리소스들만 문서화 시킬 수도 있습니다.

Path.Selectors.ant("/v1/**")

 

swaggerInfo

swaggerInfo를 세팅하면 문서에 대한 설명과 작성자 정보를 노출시킬 수 있습니다.\

 

springdoc swagger는 별도의 configuration 설정 없이 사용이 가능하다!


UserController 수정

package org.ziaho.ziahorestapi.controller.v1;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import org.ziaho.ziahorestapi.entity.User;
import org.ziaho.ziahorestapi.repo.UserJpaRepo;

import java.util.List;

@Api(tags = {"1. User"}) // UserController를 대표하는 최상단 타이틀 영역에 표시될 값을 세팅합니다.
@RequiredArgsConstructor // class상단에 선언하면 class내부에 final로 선언된 객체에 대해서 Constructor Injection(의존성 주입)을 수행합니다.
                        // 해당 어노테이션을 사용하지 않고 선언된 객체에 @Autowired를 사용해도 됩니다.
@RestController // 결과 데이터를 JSON형식으로 내보냅니다.
@RequestMapping(value = "/v1") // api resource를 버전별로 관리하기 위해 /v1 을 모든 리소스 주소에 적용되도록 합니다.
public class UserController {

    private final UserJpaRepo userJpaRepo;

    @ApiOperation(value = "회원 조회", notes = "모든 회원을 조회한다.") // 각각의 리소스에 제목과 설명을 표시하기 위해 세팅합니다.
    @GetMapping(value = "/user")
    public List<User> findAllUser() { // user테이블에 있는 데이터를 모두 읽어옵니다. 데이터가 한개 이상 일 수 있으므로 리턴타입은 List<User>로 선언합니다.
        // Jpa를 사용하면 기본적으로 CRUD에 대해서는 별다른 설정없이 쿼리를 질의할 수 있도록 메소드를 지원합니다.
        // select * from user와 같음
        return userJpaRepo.findAll();
    }

    @ApiOperation(value = "회원 입력", notes = "모든 회원을 입력한다.") // 각각의 리소스에 제목과 설명을 표시하기 위해 세팅합니다.
    @PostMapping(value = "/user")
    public User save(@ApiParam(value = "회원아이디", required = true) @RequestParam String uid,
                     @ApiParam(value = "이름", required = true) @RequestParam String name) { // 파라미터에 대한 설명을 보여주기 위해 세팅합니다.
        // user 테이블에 데이터 1건을 입력합니다.
        // Jpa를 사용하면 기본적으로 CRUD에 대해서는 별다른 설정없이 쿼리를 질의할 수 있도록 메소드를 지원합니다.
        // insert into user(msrl, name, uid) values(null, ?, ?)와 같음
        User user = User.builder()
                .uid("test1@test.com")
                .name("테스트1")
                .build();
        return userJpaRepo.save(user);
    }

}

 

@Api(tags = {"1.User"})

UserController를 대표하는 최상단 타이틀 영역에 표시될 값을 세팅합니다.

 

@ApiOperation(value = "제목", notes = "설명")

각각의 resource에 제목과 설명을 표시하기 위해 세팅합니다.

 

@RequestParam ~~~

파라미터에 대한 설명을 보여주기 위해 세팅합니다.

 

spirngdoc swagger는 springfox swagger2 버전과 어노테이션이 다르기때문에 수정부분은 아래에 후술하겠음


테스트 해보기

서버를 실행하고 아래의 URL을 실행하면 Swagger 화면을 확인 할 수 있습니다.

http://localhost:8080/swagger-ui.html

 

Swagger 3.0 버전 이상부터는 아래 주소를 사용!

http://localhost:8080/swagger-ui/index.html


서버 구동시에

Caused by: java.lang.IllegalStateException: Failed to introspect Class [springfox.documentation.swagger2.web.Swagger2Controller] from ClassLoader [jdk.internal.loader.ClassLoaders$AppClassLoader@4e25154f]

위와같은 에러가 발생하였다.

 

Java 버전이 안맞아서 ClassLoader로부터 못가져오는건가 싶어서 Java 버전도 맞춰보고 gradle 업데이트도 다시 진행 해 보았지만 여전히 똑같은 오류가 계속 발생,,,

 

그래서 내용을 더 찾아보다 보니

SpringBoot 3.0 버전 이상에서 부터는 Swagger 또한 3.0버전 이상으로 설정해 주어야 사용 가능하다고 한다!!!

implementation("io.springfox:springfox-boot-starter:3.0.0")
implementation("io.springfox:springfox-swagger-ui:3.0.0")

build.gradle에 swagger를 3.0.0버전으로 수정 해 주고, 서버를 재구동 했더니 정상적으로 구동되었다.

 

하지만....

위와 같은 에러와 함께 화면이 나오지 않았다.


찾아보니 SpringBoot3를 springfox swagger가 지원하지 않아 사용하기 어려울 것으로 예상

 

스프링부트에 Swagger 적용하기 (velog.io)

 

스프링부트에 Swagger 적용하기

1. Swagger (스웨거) Web API를 자동으로 문서화 해주는 오픈소스 소프트웨어 2. 스프링부트에 적용하기 (1) build.gradle (2) Configuration 👇 오류난 코드 다른 블로그에서 하라는 대로 작성해서 실행하고 ht

velog.io

 

스프링 부트 2에서 스프링 부트 3로 업그레이드 가이드 (tistory.com)

 

스프링 부트 2에서 스프링 부트 3로 업그레이드 가이드

0. 시작하며 22년 11월 스프링 부트 3가 정식 릴리즈 되었습니다. 18년 3월 1일 스프링 부트 2가 나온 이후 3년 9개월의 시간이 지난 오랜만의 메이저 업데이트 입니다. 기존의 프로젝트를 스프링 부

covenant.tistory.com

Spring Boot 프로젝트(Gradle) 에서의 Swagger 3.0.0 설정 방법 (velog.io)

 

Spring Boot 프로젝트(Gradle) 에서의 Swagger 3.0.0 설정 방법

이 글은 스프링부트, Gradle 환경에서 API 문서 Swagger를 설정하는 방법에 대해 다룹니다.build.gradle 파일에 아래 코드를 추가합니다.api() 함수는 스웨거 설정을 위해 필요하고, apiInfo()는 설정해주지

velog.io

Springboot에서 API Docs (Springdoc) 사용하는 방법 (1) (tistory.com)

 

Springboot에서 API Docs (Springdoc) 사용하는 방법 (1)

지난번에 JavaDoc이라던지 JSDoc을 사용하는 방법에 대해서 다룬적이 있었다. 이와 마찬가지 맥락으로 API Docs을 생성하는 방법도 있다. MSA가 유행을 하며 이로 구성된 시스템은 수많은 API Service를

oingdaddy.tistory.com

 

 

Spring Boot3 버전으로 업그레이드 되면서 Swagger 사용 오류.

참고 글 기록

3버전 이상에서도 사용 가능한 방법 찾은 이후에 수정 할 예정.

→ 해결했습니다 ㅎㅎ

 

다음 단계 포스팅에서는 Swagger 대신 Postman으로 테스트 진행 예정


해결했다~~~~!!!

SpringBoot가 2버전에서 3버전으로 업그레이드 되면서, javax패키지가 jakarta로 변경되었다.

그런데 springfox swagger는 jakarta를 지원하지 않기 때문에 SpringBoot 3버전 이상에서는 사용할수가 없었던것!!

 

대신 springdoc swagger는 SpringBoot 3버전 이상을 지원하기때문에 springdoc swagger를 사용한다.

build.gradle에 아래와 같은 소스를 추가한다.

implementation("org.springdoc:springdoc-openapi-starter-webmvc-ui:2.0.2")
implementation("org.springdoc:springdoc-openapi-starter-webmvc-api:2.0.2")

 


UserController 수정하기

package org.ziaho.ziahorestapi.controller.v1;

//import io.swagger.annotations.ApiParam;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import org.ziaho.ziahorestapi.entity.User;
import org.ziaho.ziahorestapi.repo.UserJpaRepo;

import java.util.List;

@Tag(name = "1. User", description = "UserController") // UserController를 대표하는 최상단 타이틀 영역에 표시될 값을 세팅합니다.
@RequiredArgsConstructor // class상단에 선언하면 class내부에 final로 선언된 객체에 대해서 Constructor Injection(의존성 주입)을 수행합니다.
                        // 해당 어노테이션을 사용하지 않고 선언된 객체에 @Autowired를 사용해도 됩니다.
@RestController // 결과 데이터를 JSON형식으로 내보냅니다.
@RequestMapping(value = "/v1") // api resource를 버전별로 관리하기 위해 /v1 을 모든 리소스 주소에 적용되도록 합니다.
public class UserController {

    private final UserJpaRepo userJpaRepo;

    @Operation(summary = "회원 조회", description = "모든 회원을 조회한다.") // 각각의 리소스에 제목과 설명을 표시하기 위해 세팅합니다.
    @GetMapping(value = "/user")
    public List<User> findAllUser() { // user테이블에 있는 데이터를 모두 읽어옵니다. 데이터가 한개 이상 일 수 있으므로 리턴타입은 List<User>로 선언합니다.
        // Jpa를 사용하면 기본적으로 CRUD에 대해서는 별다른 설정없이 쿼리를 질의할 수 있도록 메소드를 지원합니다.
        // select * from user와 같음
        return userJpaRepo.findAll();
    }

    @Operation(summary = "회원 입력", description = "모든 회원을 입력한다.") // 각각의 리소스에 제목과 설명을 표시하기 위해 세팅합니다.
    @PostMapping(value = "/user")
    public User save(@Parameter(name = "회원아이디", required = true) @RequestParam String uid,
                     @Parameter(name = "이름", required = true) @RequestParam String name) { // 파라미터에 대한 설명을 보여주기 위해 세팅합니다.
        // user 테이블에 데이터 1건을 입력합니다.
        // Jpa를 사용하면 기본적으로 CRUD에 대해서는 별다른 설정없이 쿼리를 질의할 수 있도록 메소드를 지원합니다.
        // insert into user(msrl, name, uid) values(null, ?, ?)와 같음
        User user = User.builder()
                .uid("test1@test.com")
                .name("테스트1")
                .build();
        return userJpaRepo.save(user);
    }

}

@Api(tags = {"1.User"})@Tag(name = "1. User", description = "UserController")

UserController를 대표하는 최상단 타이틀 영역에 표시될 값을 세팅합니다.

name에는 최상단 타이틀 영역에 표시될 값을 세팅하고

description에는 설명 내용을 세팅합니다.(description은 작성하지 않아도 됩니다.)

 

@ApiOperation(value = "제목", notes = "설명") @Operation(summary = "제목", description="모든 회원을 조회한다."

각각의 resource에 제목과 설명을 표시하기 위해 세팅합니다.

value → summary

notes → description

 

@ApiParam ~~~ → @Param ~~~

파라미터에 대한 설명을 보여주기 위해 세팅합니다.

value → name

 

그 외 어노테이션 변경점은 아래 문서를 참고하시면 됩니다.

Migrating from SpringFox (springdoc.org)

 

Migrating from SpringFox

Remove springfox and swagger 2 dependencies. Add springdoc-openapi-ui dependency instead. org.springdoc springdoc-openapi-ui 1.6.14 Replace swagger 2 annotations with swagger 3 annotations (it is already included with springdoc-openapi-ui dependency). Pack

springdoc.org


결과 확인


위와 같이 설정을 완료하고 테스트를 진행하기 위해 서버를 구동시켰는데

jakarta.validation.NoProviderFoundException: Unable to create a Configuration, because no Jakarta Bean Validation provider could be found. Add a provider like Hibernate Validator (RI) to your classpath.

다음과 같은 에러가 발생하였다...

 

해당 에러는 Bean Validation Provider dependency를 추가해줌으로 써 해결할 수 있었다.

build.gradle에 아래 소스 추가!

implementation("org.springframework.boot:spring-boot-starter-validation")

Bean 유효성을 검증해주는 dependency를 추가해 줌으로써 해결.


http://localhost:8080/swagger-ui/index.html

위 주소로 접속하면

 

다음과 같은 Swagger 화면을 확인 할 수 있습니다.

 

여기까지 SpringBoot에 Swagger 설정하는 방법을 알아보았습니다.

실무에서 개발 문서를 작성하고 테스트 해야하는 일이 자주 있는데, Swagger를 사용하면 번거롭게 문서를 추가할 필요도 없을 뿐더러 즉시 테스트도 가능하므로 작업에 대한 생산성을 높일 수 있게 됩니다.

 

다만 Swagger를 사용하면 Controller의 소스가 다소 지저분 해 질 수도 있다는 단점도 있습니다.


출처

SpringBoot2로 Rest api 만들기(4) – Swagger API 문서 자동화 (daddyprogrammer.org)

 

SpringBoot2로 Rest api 만들기(4) – Swagger API 문서 자동화

앞서 개발한 api는 테스트를 위해 Postman을 따로 설치해야 하는 불편함이 있었습니다. 요번에 설명하려는 Swagger라는 문서 자동화 툴은 간단한 설정만으로도 테스트 가능한 Web UI를 지원하여 api를

www.daddyprogrammer.org

spring - Unable to create a Configuration, because no Bean Validation provider could be found. Add a provider like Hibernate Validator (RI) to your classpath - Stack Overflow

 

Unable to create a Configuration, because no Bean Validation provider could be found. Add a provider like Hibernate Validator (R

Today,I am looking into send Email, but when I add <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <

stackoverflow.com

Springboot 3.x에 Swagger를 적용시켜보자! (velog.io)

 

Springboot 3.x에 Swagger를 적용시켜보자!

Springboot 3.0.1에서 Swagger 3.0.0을 적용 중 발생하는 에러들을 해결해 보자

velog.io

Spring swagger 3 사용방법(springdoc-openapi-ui) (tistory.com)

 

Spring swagger 3 사용방법(springdoc-openapi-ui)

스프링 부트에서 'springdoc-openapi-ui'를 사용하여 swagger3를 적용하는 방법에 대해서 살펴보겠습니다. 'springfox-swagger-ui', 'springfox-swagger2'를 사용하는 방법과는 다른 방법이며, 오로지 'springdoc-openapi-ui

wildeveloperetrain.tistory.com

스프링 부트 2에서 스프링 부트 3로 업그레이드 가이드 (tistory.com)

 

스프링 부트 2에서 스프링 부트 3로 업그레이드 가이드

0. 시작하며 22년 11월 스프링 부트 3가 정식 릴리즈 되었습니다. 18년 3월 1일 스프링 부트 2가 나온 이후 3년 9개월의 시간이 지난 오랜만의 메이저 업데이트 입니다. 기존의 프로젝트를 스프링 부

covenant.tistory.com