기록 및 회고

Spring Rest Docs 트러블 슈팅

Debin 2022. 9. 1.
반응형

스프링 진영에서는 API 명세서로 사용하는 대표적인 두 가지가 있다.

바로 Swagger와 Spring Rest Docs다.

간단하게 설명하면 Swagger는 도입이 매우 편리하지만 운영 코드가 지저분해지고 기능적인 보장을 할 수 없다.

Spring Rest Docs는 테스트를 기반으로 작성되므로 운영 코드가 지저분해지지 않고 기능적인 보장을 한다.

다만 적용하는데 꽤 많은 시간이 소요된다.

 

저번 동아리 프로젝트는 빠르게 개발을 해야하므로 Swagger을 도입했었다.

이번에는 졸업 프로젝트를 하면서 새로운 기술을 도입해보고 싶었기에 Spring Rest Docs를 도입하기로 결정했다.

 

이번 포스팅에서는 구체적인 도입 방법보다는 트러블 슈팅과 해결 과정을 기록하려고 한다.

Spring Rest Docs를 도입하면서 참고한 레퍼런스는 다음과 같다.

Spring Rest Docs 참고자료

https://techblog.woowahan.com/2597/

https://docs.spring.io/spring-restdocs/docs/current/reference/html5/#documenting-your-api-request-parts-payloads

https://www.inflearn.com/course/%ED%98%B8%EB%8F%8C%EB%A7%A8-%EC%9A%94%EC%A0%88%EB%B3%B5%ED%86%B5-%EA%B0%9C%EB%B0%9C%EC%87%BC/dashboard

 

제일 먼저 로컬에 적용하고 서버에 배포하는 것 까지는 성공했다. 그러나 Docs를 커스터마이징하면서 문제가 발생했다.

첫 번째 문제

index.adoc를 깔끔하게 하기 위해 member.adoc를 추출해 작성했다.

인텔리제이에서 미리보기를 통해 잘 된 것을 확인할 수 있다.

그러나 웹 애플리케이션을 띄우면 다음과 같은 화면이 뜬다.

즉 적용이 안되버린 것이다. 많은 레퍼런스들도 다음과 같은 include를 문법을 사용했고,

공식 문서를 보면 해당 위치에 있는 파일을 include 하는 것 같은데.. 꽤 당황했다.

정말 온갖 짓을 다 한 것 같다. gradle bootJar, build, clean build, clean 등 브라우저 캐시도 지우면서 별 짓을 다했다.

무엇보다 힘들었던 것은 에러 로그가 없다는 것이었다. 그러다가 문득 어느 한 로그를 발견했다.

과정은 다음과 같다. clean을 하고 adoc이 담겨있는 static 디렉토리를 지우고 bootJar를 눌렀었다.

그러면 다음과 같은 경고가 출력됐다.

심각: index.adoc: line 9: include file not found: /Users/ansubin/Desktop/graduation/backend/member.adoc

경로 오류인 것 같다. 그래서 index.adoc를 다음과 같이 수정했다.

인텔리제이에서는 빨간줄이 나오지만 웹 애플리케이션을 띄우면 어떨까..?!

정상적으로 뜬다!!! 정말 최근 만난 오류 중에 제일 얼탄 것 같다. 에러 로그의 소중함을 다시금 느낄 수 있었다.

두 번째 문제

이렇게 문제를 해결하고 배포(CI/CD)를 통해 서버를 다시 딱 띄웠으나!!! docs/index.html로 가면 whitable 에러 페이지가 나왔다.

일단 build.gradle 코드는 다음과 같다.

plugins {
	id 'org.springframework.boot' version '2.7.3'
	id 'io.spring.dependency-management' version '1.0.13.RELEASE'
	id 'java'
	id "org.asciidoctor.jvm.convert" version "3.3.2"
}

group = 'wayc'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'

configurations {
	asciidoctorExt
	compileOnly {
		extendsFrom annotationProcessor
	}
}

repositories {
	mavenCentral()
}

ext {
	snippetsDir = file('build/generated-snippets')
	asciidocVersion = "2.0.6.RELEASE"
}

dependencies {

	//생략

	//spring rest docs
	asciidoctorExt "org.springframework.restdocs:spring-restdocs-asciidoctor:${asciidocVersion}"
	testImplementation "org.springframework.restdocs:spring-restdocs-mockmvc:${asciidocVersion}"

}

//--spring rest docs --//

test {
	outputs.dir snippetsDir
}

asciidoctor {
	inputs.dir snippetsDir
	configurations 'asciidoctorExt'
	dependsOn test
}

bootJar {
	dependsOn asciidoctor
//	from ("${asciidoctor.outputDir}") {
//		println ">>>>" + asciidoctor.outputDir //build 파일에 생성된다. static으로 옮겨야함.
//		into 'static/docs'
//	}
	copy {
		from asciidoctor.outputDir
		into 'src/main/resources/static/docs'
	}
}

//--spring rest docs --//

clean {
	delete file('src/main/generated')
}

jar{
	enabled(false) //plain.jar 생성을 막음.
}

tasks.named('test') {
	useJUnitPlatform()
}

결국 resources 내부의 static/docs가 안생긴 것이라고 생각했다. 그래서 ./gradlew clean을 하고 build를 시켜보았다.

build를 명령어를 통해서는 static/docs가 생성이 안됐다. 아마 bootJar 명령어에 docs 생성 설정을 해서 그런 것 같은데 

build.gradle에서 build에 bootJar 내용을 복사 붙여넣기 했지만 해결되지는 않았다.

일단 오류 수정이 급하므로 깃헙 액션 파일을 다음과 같은 부분을 추가했다.

    - name: boot Jar
      run: ./gradlew bootJar

    - name: Build Application
      run: ./gradlew build

일단 해결 완료!!! 현명하게 해결한 것 같지는 않지만 차후에 더 좋은 방법을 찾아봐야겠다.

 

이상으로 포스팅을 마칩니다. 감사합니다.

반응형

댓글