[SpringBoot] API 문서 생성 - Swagger 연동하기 (SpringFox)

2023. 7. 25. 05:14
반응형

이번 포스팅에서는 API 문서 생성을 위해서 Swagger를 연동하는 방법을 알아보도록 하겠다.

 

 

API 문서의 필요성

서비스의 개발은 기본적으로 팀단위로 이루어진다. 그리고 거의 대부분의 프로젝트들은 서버 백엔드 개발자들이 만들어둔 API를 사용하여 웹파트의 프론트엔드 개발자, 모바일이면 안드로이드, IOS 개발자, 그리고 그 외의 응용 프로그램 개발자들까지 서버의 비즈니스 로직과 데이터베이스의 접근을 위해서 API를 사용한다. 그런데 백엔드 개발자들이 일일이 API 사용법을 알려주기에는 비용적 측면에서 수지타산이 맞지 않다. 그래서 백엔드 개발자들은 API 개발과 함께 체계적인 문서를 다른 팀원들에게 제공해주어야 할 필요성이 있다.

가장 잘 알려진 문서화 도구들은 REST API 개발시에는 Swagger, GraphQL일 시에는 Playground 등이 있다. 

스프레드시트 등 수동작성에 비교해 보았을 때 생산성 있고, 자동화된 형태의 문서를 생성할 수 있다는 장점이 존재한다.

 

OpenAPI 사양 (이전의 Swagger 사양)은 REST API에 대한 API 설명 형식입니다. OpenAPI 파일을 사용하면 다음을 포함하여 전체 API를 설명할 수 있습니다.

 

Swagger란?

Swagger 는 REST API를 설계, 구축, 문서화 및 사용하는 데 도움이 되는 OpenAPI 사양을 기반으로 구축된 오픈 소스 도구 세트입니다.  - https://swagger.io/docs/specification/about/

 

About Swagger Specification | Documentation | Swagger

What Is OpenAPI? OpenAPI Specification (formerly Swagger Specification) is an API description format for REST APIs. An OpenAPI file allows you to describe your entire API, including: Available endpoints (/users) and operations on each endpoint (GET /users,

swagger.io

 

Swagger를 사용해 본 경험으로는 주요 기능으로는 아래와 같은 API의 명세를 정의하는 것이 가능했다.

  • 기능별 URL과 HTTP Method 및 엔드 포인트 
  • 입력 및 출력(Request/Response) 파라미터의 유형과 자료형 및 모델 명시
  • API별 인증 방식 정의

 


패키지 Dependency 추가

 

 build.gradle

group = 'com.sklookiesmu'
version = '0.0.1-SNAPSHOT'

java {
	sourceCompatibility = '11'
}

configurations {
	compileOnly {
		extendsFrom annotationProcessor
	}
}

repositories {
	mavenCentral()
}

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
	implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
	implementation 'org.springframework.boot:spring-boot-starter-validation'
	implementation 'org.springframework.boot:spring-boot-starter-web'
	implementation 'org.springframework.boot:spring-boot-devtools'
	implementation 'com.github.gavlyukovskiy:p6spy-spring-boot-starter:1.5.6'
	implementation 'com.fasterxml.jackson.datatype:jackson-datatype-hibernate5'
	runtimeOnly 'org.mariadb.jdbc:mariadb-java-client:2.7.4'
	compileOnly 'org.projectlombok:lombok'
	annotationProcessor 'org.projectlombok:lombok'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'
    
	//JUnit4 추가
	testImplementation("org.junit.vintage:junit-vintage-engine") {
		exclude group: "org.hamcrest", module: "hamcrest-core"
	}
    
	//Springfox swagger
	implementation 'io.springfox:springfox-boot-starter:3.0.0'
	implementation 'io.springfox:springfox-swagger-ui:3.0.0'

}

하단의 Springfox Swagger를 추가하는 부분을 통하여 Swagger docs 사용에 필요한 디펜던시를 추가해준다.

유의할 점은 해당 포스팅에서는 Swagger 3점대 버전을 사용한다는 것이다.

Swagger은 2점대와 3점대에서, 패키지 구조, 설정, 모델 속성 등에서 큰 차이가 있다는 점을 유의하도록 하자.

참고로 본 포스팅에서는 Spring-boot 2.7.13 버전을 사용하고 있으므로, Spring-boot 3 버전 이상에서는 아래의 코드와 다른 형태로 작성해야 할 확률이 있으니 유의하자.

 

 

2024-01-15 : Spring Boot의 공식 지원 기간이 2점대는 종료되었으므로 3점대 버전의 사용을 권장한다. 이에 따라 Spring 3점대에서 의 Swagger 설정법을 다음 포스팅에 작성해두었다.
https://sjh9708.tistory.com/169

 

[Spring Boot] SpringDoc 설정을 통한 Swagger 연동

이전에 Spring Boot 프로젝트에 Swagger를 연동해 본 적이 있었다. 최근 Spring Boot의 지원 버전이 3점대로 올라감과 동시에, 2점대에서 Swagger 사용 목적으로 많이 사용되는 SpringFox가 안타깝게도 제대로

sjh9708.tistory.com

 

 

 


Swagger Configuration 작성

 

@Configuration
public class SwaggerConfiguration {

    @Bean
    public Docket api(){
        return new Docket(DocumentationType.OAS_30)
                .useDefaultResponseMessages(false)
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.sklookiesmu.wisefee.api"))
                .paths(PathSelectors.any())
                .build()
                .apiInfo(apiInfo())
    }

    private ApiInfo apiInfo(){
        return new ApiInfoBuilder()
                .title("Wisefee API Document")
                .description("This is Wisefee API Document")
                .version("1.0")
                .build();
    }


}

 

Swagger를 설정하기 위한 SwaggerConfiguration 클래스이다.

@Configuration 애노테이션을 사용하여 Spring의 설정 클래스임을 나타낸다.


api() 

Docket 객체를 생성하여 사용할 Swagger 설정을 구성
DocumentationType.OAS_30을 사용하여 Swagger OpenAPI 3.0 스펙을 사용하도록 설정

  • useDefaultResponseMessages(false) : 기본 응답 메시지를 사용하지 않도록 설정
  • select() :  API 문서화 대상을 선택
  • apis(RequestHandlerSelectors.basePackage()) : 해당 패키지에 있는 API 컨트롤러들만 문서화 대상으로 설정
  • paths(PathSelectors.any()) : 위 패키지의 모든 경로를 문서화 대상으로 설정
  • build() : Docket 객체를 빌드하여 설정을 완료
  • apiInfo() : apiInfo() 메서드를 호출하여 API 정보를 설정


apiInfo()

API 문서에 표시될 정보를 설정

  • ApiInfoBuilder를 사용하여 API 정보를 빌드
  • title() : 문서의 제목 설정
  • description() : 문서의 설명 설정
  • version() : API 버전 설정(프로젝트의 API 버전을 명시하면 됨)
  • build() :  ApiInfo 객체를 빌드

 

 


 

API 문서화

 

@Api(tags = "회원 API")
@RestController
@RequiredArgsConstructor
public class MemberApiController {
    private final MemberService memberService;

    private final ModelMapper modelMapper;

    @ApiOperation(value = "회원 전체 조회")
    @GetMapping("/api/v1/member")
    public ResponseEntity<List<MemberResponseDto>> findMembers(
            @ApiParam(value = "정렬 순서 (asc 또는 desc)", defaultValue = "asc")
            @RequestParam(value = "order", defaultValue = "asc") String order
    ){
        List<Member> members = memberService.getMembers(order);
        List<MemberResponseDto> result = members.stream()
                .map(e -> modelMapper.map(e, MemberResponseDto.class))
                .collect(Collectors.toList());
        return ResponseEntity.status(HttpStatus.OK).body(result);
    }
    
    @ApiOperation(value = "해당 ID의 회원 조회")
    @GetMapping("/api/v1/member/{id}")
    public ResponseEntity<MemberResponseDto> findMemberById(
            @ApiParam(value = "회원 PK", required = true)
            @PathVariable("id") Long id
    ){
        Member member = memberService.getMember(id);
        if(member == null){
            return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
        }
        MemberResponseDto result = modelMapper.map(member, MemberResponseDto.class);
        return ResponseEntity.status(HttpStatus.OK).body(result);
    }

}

Controller에서 해당 Annotation을 기반으로 기반으로 Swagger가 문서를 자동으로 생성하고 API에 대한 정보를 제공한다.

 

 

@Api(tags = "회원 API"):
- 해당 컨트롤러에 대한 Swagger API 그룹(태그)을 지정


@ApiOperation(value = "회원 전체 조회")
- 해당 메서드에 대한 API 연산(Operation)에 대한 정보
- value 속성은 API 연산의 간단한 설명을 설정


@ApiParam(value = "정렬 순서 (asc 또는 desc)", defaultValue = "asc")
- 해당 메서드의 @PathVariable 파라미터에 대한 정보를 제공
- value 속성은 파라미터의 설명을 설정
- defaultValue 속성은 파라미터의 기본값을 설정



 

 

@Data
@NoArgsConstructor
@AllArgsConstructor
@ApiModel(description = "회원 추가 요청 DTO")
public class MemberResponseDto {

    @ApiModelProperty(value = "회원 PK", required = true)
    @NotNull
    private Long id;

    @ApiModelProperty(value = "회원 닉네임", required = true)
    @NotNull
    private String name;

    @ApiModelProperty(value = "회원 이메일", required = true)
    @NotNull
    private String email;
}

요청이나 응답 객체로 사용되는 DTO에도 API 사용 문서화를 할 수 있다. 이를 기반으로, 어떤 Input과 Output을 제공받는지에 대한 명세또한 가능하다.

 

@Data 

getter, setter, equals, hashCode, toString 메서드를 자동으로 생성

@NoArgsConstructor

파라미터 없는 생성자를 자동으로 생성합니다. 이것은 기본 생성자를 생성

@AllArgsConstructor

모든 필드를 파라미터로 받는 생성자를 자동으로 생성.

 
@ApiModel 

해당 클래스에 대한 Swagger에서 사용될 API 모델 정보를 설정
description : 해당 모델에 대한 설명


@ApiModelProperty

해당 필드에 대한 Swagger에서 사용될 API 문서 정보를 제공
value : 해당 필드의 설명을 설정


@NotNull

Swagger에서 @ApiModelProperty와 함께 사용하면, 필수 입력 필드임을 문서에 나타낼 수 있음.

 

 

 


Swagger 문서 접속

 

http://localhost:8080/swagger-ui/index.html에 들어가게 되면 자동화되어 생성된 Swagger 문서를 볼 수 있다.

위의 Annotation을 통해 설정된 API 스펙 명시가 잘 이루어진 것을 확인할 수 있다.

 

우측에 자물쇠를 보면 Spring Security와 관련되어 인증과 인가 설정 또한 할 수 있는 것을 확인할 수 있는데, 이는 다음 포스팅에서 JWT 인증을 다룬 이후 설명해보도록 하겠다.

반응형

BELATED ARTICLES

more