RestDocs+Swagger UI 사용 중 마주한 Swagger Fetch Error

dev-jjun·2024년 1월 29일
0

트러블 슈팅

목록 보기
8/8
post-thumbnail

오류 사항

openapi3을 이용해 RestDocs + Swagger UI를 이용한 API 문서 자동화를 세팅하였다. 이때, 컨트롤러 단위 테스트가 성공하면 build.gradle에서 설정해준 디렉터리 위치에 파일이 업데이트 되는 플로우이다.

// build.gradle

openapi3 {
	servers = [
			{ url = properties["server.BASE_URL"] },
			{ url = "http://localhost:8080" }
	]
	title = "모티부 API 명세서"
	description = "Motivoo REST Docs with SwaggerUI"
	version = "v0.0.1"
	format = "json"
	outputFileNamePrefix = "open-api-3.0.1"
	outputDirectory = 'build/resources/main/static/docs'
}

Swagger UI가 적용될 파일의 위치는 application.yml에서 아래와 같이 지정해주었다.

// application.yml 

springdoc:
  swagger-ui:
    path: /swagger   # 접속할 URL 경로
    url: /docs/open-api-3.0.1.json  # 파일 위치

테스트를 추가하고 통과하면 정상적으로 파일에는 반영이 되었지만, 특정 시점부터 갑자기 동작하지 않았다. 이를 로컬에서 실행하여 localhost:8080/swagger 로 접속했을 때는 fetch error가 뜨며 파일을 읽어들이지 못하는 문제가 발생했다.

문제 원인 및 해결 방안

TRY1. Security 관련 설정 추가

private static final String[] *AUTH_WHITELIST* = {    
		"/", "/**", "/oauth/**", "/api/**", 
		"/actuator/health","/withdraw", "/mission/**", "/home",    
		"/swagger/**", "/swagger-ui/**"
};

위와 같이 White List에 Swagger 관련 URL을 모두 넣어주고, 해당 url 접속에 대한 인증 필터를 거치지 않도록 했다.

하지만 이 방법은 아니었나 보다. Fail..!

TRY2. Controller 의 접근 제어 protected 이하 ✅

Controller 단위 테스트이다 보니 문제원인을 파악하는 데 있어, 컨트롤러 클래스 단으로 다시 트래킹 해보았다.

잘 살펴보니 생성자 주입을 위한 @RequiredArgsConstructor 의 접근 제어가 protected로 설정되어 있는 것을 확인할 수 있었다. 이는 하위 클래스에서만 컨트롤러에 접근 가능하고 외부에서는 접근을 못하도록 제한하는 것이므로 절대 좋지 않은 방식이라고 생각한다.

protected의 범위에 벗어나는 테스트 클래스에서는 당연히 위 Controller 클래스의 생성자에 접근할 수 없었고, 해당 클래스의 인스턴스를 생성하는 것이 불가능해졌다. 의존성 주입이 안 되니 Swagger 실행도 거부당한 것으로 예상된다.

TRY3. WebConfig - CORS 설정 ✅

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

	@Override
	public void addCorsMappings(CorsRegistry registry) {
		registry.addMapping("/**")
			.allowedOrigins("*")
			.allowedOriginPatterns("*")
			.allowedMethods("*");
	}

	@Override
	public void addResourceHandlers(ResourceHandlerRegistry registry) {
		registry.addResourceHandler("/swagger-ui/**")
			.addResourceLocations("classpath:/META-INF/resources/docs/");
	}
}

참고 자료를 통해 CORS 에러로 인한 fetch error의 가능성이 있음을 열어두고, WebConfig 클래스를 추가하였다.

하지만 우리는 https 배포를 따로 설정해주지 않은 상태이므로, 사실상 CORS 관련 설정은 필요없는 상태였다. 따라서 controller의 접근 제어 변경과 WebConfig 파일 자체를 삭제해버리니 드디어 동작하였다!!!! 😭😹

📑 참고 자료

[Spring] Swagger ui Failed to load API definition 에러

[Swagger] Swagger 3 TypeError: Failed to fetch

404 not found on swagger UI · Issue #361 · springdoc/springdoc-openapi

profile
서버 개발자를 꿈꾸며 성장하는 쭌입니다 😽

0개의 댓글