Rest API를 자동으로 문서화해주는 API입니다. 프론트엔드와의 협업을 위해서 적용하고자 합니다.
23년 2월 10일 현재 최신 버전인 Springdoc 1.6.14버전을 설치하였습니다.
Swagger 3버전을 이용할 예정입니다.
https://mvnrepository.com/artifact/org.springdoc/springdoc-openapi-ui/1.6.14
먼저 build.gradle에 Swagger-UI 관련 Dependencies를 추가합니다.
✅ build.gradle
//추가
implementation group: 'org.springdoc', name: 'springdoc-openapi-starter-webmvc-ui', version: '2.0.2'
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-validation', version: '3.0.2'
Swagger관련 설정을 위해 Configuration 클래스도 생성합니다.
✅ SwaggerConfig
package uos.capstone.dms.swagger;
import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info;
import org.springdoc.core.models.GroupedOpenApi;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class SwaggerConfig {
@Bean
public GroupedOpenApi jwtApi() {
return GroupedOpenApi.builder()
.group("jwt-api")
.pathsToMatch("/**")
.build();
}
@Bean
public OpenAPI customOpenAPI() {
return new OpenAPI()
.components(new Components())
.info(new Info().title("8am API")
.description("DMS팀의 8am 어플리케이션 API입니다.")
.version("v1.0.0"));
}
}
여기서 OpenAPI를 생성할 때 title
, description
, version
을 바꾸면 아래 나올 페이지의 내용도 바뀌게 됩니다.
Swagger-UI는 http://localhost:8080/swagger-ui/index.html
로 들어가서 확인할 수 있습니다. 하지만, 현재 Spring Security의 Filter에서 해당 URL로의 접근은 인증이 필요하기 때문에 permitAll()
하도록 코드를 수정해야 합니다.
✅ SecurityConfig
...
//추가
private static final String[] URL_TO_PERMIT = {
"/member/login",
"/member/signup",
"/v3/api-docs/**",
"/swagger-ui/**",
"/auth/**"
};
...
수정을 완료하고 http://localhost:8080/swagger-ui/index.html
로 접속하면 아래와 같은 페이지가 생성됩니다.
각 Controller의 Rest API에 @Operation
어노테이션을 적용하여 설명을 적을 수 있습니다.
✅ MemberController
@Tag(name = "사용자 관련", description = "사용자 관련 API")
@RestController
@Log4j2
@RequestMapping("/member")
@RequiredArgsConstructor
public class MemberController {
private final MemberService memberService;
private final PasswordEncoder passwordEncoder;
@Operation(summary = "회원가입")
@PostMapping("/signup")
public ResponseEntity<String> memberSignup(@ModelAttribute MemberRequestDTO memberRequestDTO) {
log.info(memberRequestDTO);
memberRequestDTO.setPassword(passwordEncoder.encode(memberRequestDTO.getPassword()));
memberService.signup(memberRequestDTO);
return new ResponseEntity<>("", HttpStatus.OK);
}
@Operation(summary = "로그인")
@PostMapping("/login")
public ResponseEntity<TokenResponseDTO> memberLogin(@ModelAttribute LoginRequestDTO loginRequestDTO) {
log.info(loginRequestDTO);
TokenDTO tokenDTO = memberService.login(loginRequestDTO);
ResponseCookie responseCookie = ResponseCookie
.from("refresh_token", tokenDTO.getRefreshToken())
.httpOnly(true)
.secure(true)
.sameSite("None")
.maxAge(tokenDTO.getDuration())
.path("/")
.build();
TokenResponseDTO tokenResponseDTO = TokenResponseDTO.builder()
.isNewMember(false)
.accessToken(tokenDTO.getAccessToken())
.build();
return ResponseEntity.ok().header("Set-Cookie", responseCookie.toString()).body(tokenResponseDTO);
}
@Operation(summary = "회원정보 호출")
@GetMapping("/getMemberData")
public ResponseEntity<MemberDTO> loadMemberData() {
return ResponseEntity.ok(memberService.getMember(SecurityUtil.getCurrentUsername()));
}
}
수정한 뒤 다시 서버를 열어 페이지를 로딩해보면 URI마다 요청 파라미터와 응답 값을 볼 수 있습니다.
💡 추가적으로 HTTP Status마다 설정도 가능하지만 이번 글에서는 생략하겠습니다.