๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

Spring

Spring Rest Docs ๋„์ž… ์‹œ, Maven๊ณผ Asciidoctor ๋ฌธ๋ฒ•์ด ํ—ท๊ฐˆ๋ฆฌ๋Š” ๋ถ„๋“ค์„ ์œ„ํ•œ pom.xml ์„ค๋ช…

Spring Rest Docs๋ฅผ ๊ฒ€์ƒ‰ํ–ˆ์„ ๋•Œ, Maven์— ๋„์ž…ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ pom.xml ์„ค๋ช…์ด ๋ถ€์กฑํ•˜๋‹ค๊ณ  ๋Š๊ผˆ์Šต๋‹ˆ๋‹ค.


๊ทธ๋ž˜์„œ ์ด๋ฒˆ ๊ธ€์—์„œ๋Š” Spring Boot์™€ Maven(3.9.9 ๋ฒ„์ „) ํ™˜๊ฒฝ์—์„œ Spring Rest Docs๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ pom.xml ์„ค์ • ๋ฐฉ๋ฒ•์„ ์ •๋ฆฌํ•˜๊ณ , ๊ทธ ๊ณผ์ •์—์„œ Maven ์˜ ๋ฌธ๋ฒ•๋„ ํ•จ๊ป˜ ํ•™์Šตํ•ด๋ณด๋ ค ํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ, pom.xml ์„ค์ • ๊ฐ’๋“ค์ด Asciidoctor์™€ Maven ์ค‘ ๋ˆ„๊ตฌ์˜ ์„ค์ • ๊ฐ’์ธ์ง€ ์ดํ•ดํ•˜๋Š” ๊ฒƒ์ด ์ด ๊ธ€์˜ ๋ชฉํ‘œ์ž…๋‹ˆ๋‹ค.

 

๋˜ํ•œ, ์•„๋ž˜ ๊ทธ๋ฆผ๊ณผ ๊ฐ™์€ ๊ฒฐ๊ณผ์ฒ˜๋Ÿผ *.adoc ํŒŒ์ผ์„ HTML๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ .jar ํŒŒ์ผ์— ํฌํ•จ์‹œํ‚ค๊ณ , *.adoc ํŒŒ์ผ์€ ๋„๋ฉ”์ธ๋ณ„๋กœ ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ๋‚˜๋ˆ„์–ด ๊ด€๋ฆฌํ•˜๋Š” ๋ฐฉ์‹๋„ ํ•จ๊ป˜ ๊ตฌํ˜„ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

์™ผ์ชฝ) Maven์˜ .adoc ๋””๋ ‰ํ† ๋ฆฌ ๊ตฌ์กฐ / ์ค‘์•™) Gradle์˜ .adoc ๋””๋ ‰ํ† ๋ฆฌ ๊ตฌ์กฐ / ์˜ค๋ฅธ์ชฝ) Maven์˜ HTML๊ฒฐ๊ณผ๋ฌผ ์œ„์น˜

1. Spring Rest Docs 3.0.3 ๋ฒ„์ „์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ ํ•„์š” ์กฐ๊ฑด

  • Java 17
  • Spring Framework 6

2. ์˜์กด์„ฑ(dependency) ๋ฐ ํ”Œ๋Ÿฌ๊ทธ์ธ ์ถ”๊ฐ€

Spring Rest Docs๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด, Maven์€ pom.xml, Gradle์€ build.gradle ํŒŒ์ผ์— Build Configuration์— ๋‚˜์˜จ ๋นŒ๋“œ ์„ค์ •์„ ์ถ”๊ฐ€ํ•ด์ฃผ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

 

Maven์˜ ๊ฒฝ์šฐ, {project-version}์€ ์‚ฌ์šฉํ•  Rest Docs์˜ ๋ฒ„์ „์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฒˆ ๊ธ€์—์„œ๋Š” Rest Docs์˜ ๋ฒ„์ „์œผ๋กœ 3.0.3์„ ์‚ฌ์šฉํ•  ์˜ˆ์ •์ด๋ฏ€๋กœ, {project-version} ์ž๋ฆฌ์— 3.0.3์„ ์ž…๋ ฅํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

 

3. Rest Docs๋กœ ๋งŒ๋“  API ๋ฌธ์„œ๋ฅผ .Jar ์— ํŒจํ‚ค์ง•ํ•˜๊ธฐ

ํ”„๋กœ์ ํŠธ์—์„œ Rest Docs๋ฅผ ์ด์šฉํ•ด API ๋ฌธ์„œ๋ฅผ ๋งŒ๋“ค์—ˆ๋‹ค๋ฉด, ์ด์ œ ์ด ๋ฌธ์„œ๋ฅผ ๋‹ค๋ฅธ ์‚ฌ๋žŒ๋„ ๋ณผ ์ˆ˜ ์žˆ๋„๋ก ๋ฐฐํฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ณผ์ •์„ Rest Docs์—์„œ๋Š” "Packaging the Documentation"์ด๋ผ๊ณ  ๋ถ€๋ฆ…๋‹ˆ๋‹ค.

 

Rest Docs๋Š” ๋นŒ๋“œ ์‹œ API ๋ฌธ์„œ๋ฅผ /static/docs ๊ฒฝ๋กœ์— ํฌํ•จํ•˜์—ฌ .jar ํŒŒ์ผ ์•ˆ์— ์ž๋™์œผ๋กœ ๋ฌธ์„œ๋ฅผ ๋„ฃ์–ด์ค๋‹ˆ๋‹ค. ์ด ๋•๋ถ„์— ์šฐ๋ฆฌ๋Š” HTML ํŒŒ์ผ์„ ๋”ฐ๋กœ ์ƒ์„ฑํ•˜๊ฑฐ๋‚˜ ๋ณต์‚ฌํ•  ํ•„์š” ์—†์ด, .jar ํŒŒ์ผ๋งŒ ๋ฐฐํฌํ•˜๋ฉด ํŽธ๋ฆฌํ•˜๊ฒŒ ๋ฌธ์„œ๋ฅผ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

{IP์ฃผ์†Œ:ํฌํŠธ๋ฒˆํ˜ธ}/docs/index.html๋กœ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

Rest Docs ๊ณต์‹ ๋ฌธ์„œ์˜ "Packaging the Documentation" ์„น์…˜์—์„œ ๋‚˜์˜ค๋Š” Maven ์„ค์ • ์ค‘ 3๋ฒˆ ํ•ญ๋ชฉ์ธ <outputDirectory>๋Š” ๋ณ€ํ™˜๋œ ๋ฌธ์„œ๋ฅผ ์ €์žฅํ•  ์œ„์น˜๋ฅผ ์ง€์ •ํ•˜๋Š” ํƒœ๊ทธ์ž…๋‹ˆ๋‹ค.

 

์ด <outputDirectory>๋Š” Asciidoctor ํ”Œ๋Ÿฌ๊ทธ์ธ๊ณผ Maven ๋ฆฌ์†Œ์Šค ํ”Œ๋Ÿฌ๊ทธ์ธ ๋‘˜ ๋‹ค์—์„œ ์‚ฌ์šฉ๋˜๋Š” ํƒœ๊ทธ ์ด๋ฆ„์ด๊ธฐ ๋•Œ๋ฌธ์—, "๋ˆ„๊ตฌ์˜ ์„ค์ •์ธ์ง€"๋Š” ํ•ด๋‹น ํƒœ๊ทธ๊ฐ€ ์–ด๋–ค <plugin> ๋ธ”๋ก ์•ˆ์— ์žˆ๋Š”์ง€๋ฅผ ๋ณด๊ณ  ํŒ๋‹จํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

 

์˜ˆ๋ฅผ ๋“ค์–ด <plugin>์ด maven-resources-plugin์ด๋ผ๋ฉด, ์ด <outputDirectory>๋Š” Maven์˜ ํƒœ๊ทธ์ด๋ฉฐ, asciidoctor-maven-plugin์ด๋ผ๋ฉด Asciidoctor์˜ ํƒœ๊ทธ์ž…๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ๋Š” <plugin>์ด maven-resources-plugin ์ด๊ธฐ ๋•Œ๋ฌธ์— Maven ํƒœ๊ทธ์ž…๋‹ˆ๋‹ค.

<plugin>
  <artifactId>maven-resources-plugin</artifactId>
  ...
  <configuration>
    <outputDirectory>${project.build.outputDirectory}/static/docs</outputDirectory>
  </configuration>
</plugin>

๊ทธ๋ฆฌ๊ณ  maven-resources-plugin์€ src/main/resources/**์™€ ๊ฐ™์€ ์ •์  ๋ฆฌ์†Œ์Šค ํŒŒ์ผ๋“ค์„ .jar์— ํฌํ•จ์‹œํ‚ค๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.

 

์ด ์„ค์ •์—์„œ ์‚ฌ์šฉ๋œ ${project.build.outputDirectory}๋Š” Maven์˜ ์†์„ฑ์œผ๋กœ, ์ปดํŒŒ์ผ๋œ ํด๋ž˜์Šค ํŒŒ์ผ๋“ค์ด ์ €์žฅ๋˜๋Š” ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ํ•ด๋‹น ์†์„ฑ์˜ ๊ธฐ๋ณธ๊ฐ’์€ target/classes ์ž…๋‹ˆ๋‹ค.

Maven pom.xml ์†์„ฑ ๊ฐ’ ์ค‘ build.outputDirectory ์„ค๋ช…

* Maven์—์„œ ๋นŒ๋“œ๋œ ๊ฒฐ๊ณผ๋ฌผ์˜ ์ฃผ์†Œ ๊ธฐ๋ณธ๊ฐ’์€ target์ด๋ฉฐ, Gradle์˜ ๋นŒ๋“œ๋œ ๊ฒฐ๊ณผ๋ฌผ์˜ ์ฃผ์†Œ ๊ธฐ๋ณธ๊ฐ’์ด build ์ž…๋‹ˆ๋‹ค.

 

Maven ํ”„๋กœ์ ํŠธ๋ฅผ ๋นŒ๋“œํ•˜๋ฉด, src/main/java์— ์žˆ๋Š” .java ํŒŒ์ผ๋“ค์€ .class ํŒŒ์ผ๋กœ ์ปดํŒŒ์ผ๋˜์–ด target/classes ํ•˜์œ„์— ์ €์žฅ๋ฉ๋‹ˆ๋‹ค. ์ด ์ปดํŒŒ์ผ๋œ ๊ฒฐ๊ณผ๋ฌผ๋“ค์„ ๊ธฐ๋ฐ˜์œผ๋กœ .jar ํŒŒ์ผ์ด ๋งŒ๋“ค์–ด์ง€๊ณ , ์šฐ๋ฆฌ๋Š” ์ด .jar๋ฅผ ์‹คํ–‰ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— API๋ฌธ์„œ ์—ญ์‹œ target/classes ํ•˜์œ„์— ์œ„์น˜์‹œํ‚ต๋‹ˆ๋‹ค.

 

๊ฒฐ๋ก ์ ์œผ๋กœ ์ด ์„ค์ •์˜ ์˜๋ฏธ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

<outputDirectory>
	${project.build.outputDirectory}/static/docs
</outputDirectory>

HTML๋กœ ๋ณ€ํ™˜๋œ API ๋ฌธ์„œ๋ฅผ target/classes/static/docs ๊ฒฝ๋กœ์— ์ €์žฅํ•˜๊ณ , .jar ํŒŒ์ผ ๋‚ด์— ํ•ด๋‹น ๊ฒฝ๋กœ๋กœ ํฌํ•จ์‹œ์ผœ, /docs/index.html ๊ฒฝ๋กœ๋กœ ๋ฌธ์„œ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•œ๋‹ค.

 

์ถ”๊ฐ€๋กœ asciidoctor-maven-plugin ์„ค์ •์—์„œ ๋“ฑ์žฅํ•˜๋Š” <backend>, <doctype>, <goals> ๊ฐ™์€ ํƒœ๊ทธ๋“ค์˜ ์˜๋ฏธ๊ฐ€ ๊ถ๊ธˆํ•˜๋‹ค๋ฉด,  Asciidoctor ๊ณต์‹ ๋ฌธ์„œ ๋งํฌ๋ฅผ ์ฐธ๊ณ ํ•ด๋ณด์„ธ์š”. Ctrl+F ๋ฅผ ํ†ตํ•ด ์›ํ•˜์‹œ๋Š” ํƒœ๊ทธ์˜ ์„ค๋ช…์„ ์ฐพ์œผ์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค. 

 

์ง€๊ธˆ๊นŒ์ง€์˜ ์„ค์ •์„ ํ†ตํ•ด ์•„๋ž˜์™€ ๊ฐ™์€ pom.xml ๊ตฌ์„ฑ์ด ์™„์„ฑ๋ฉ๋‹ˆ๋‹ค.
์ด ์ƒํƒœ๋งŒ์œผ๋กœ๋„ .jar ํŒŒ์ผ์— API ๋ฌธ์„œ๊ฐ€ ํฌํ•จ๋˜๋ฏ€๋กœ, Rest Docs๋ฅผ ๋ฐฐํฌ ๊ฐ€๋Šฅํ•œ ํ˜•ํƒœ๋กœ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>3.4.3</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	...
	<properties>
		<java.version>17</java.version>
	</properties>
	<dependencies>
		<!-- API document -->
		<dependency>
			<groupId>org.springframework.restdocs</groupId>
			<artifactId>spring-restdocs-mockmvc</artifactId>
			<version>3.0.3</version>
			<scope>test</scope>
		</dependency>
	</dependencies>
	<build>
		<plugins>
			<plugin>
				<groupId>org.asciidoctor</groupId>
				<artifactId>asciidoctor-maven-plugin</artifactId>
				<version>2.2.1</version>
				<executions>
					<execution>
						<id>generate-docs</id>
						<phase>prepare-package</phase>
						<goals>
							<goal>process-asciidoc</goal>
						</goals>
						<configuration>
							<backend>html5</backend>
							<doctype>book</doctype>
						</configuration>
					</execution>
				</executions>
				<dependencies>
                	...
					<dependency>
						<groupId>org.springframework.restdocs</groupId>
						<artifactId>spring-restdocs-asciidoctor</artifactId>
						<version>3.0.3</version>
					</dependency>
				</dependencies>
			</plugin>
			<plugin>
				<artifactId>maven-resources-plugin</artifactId>
				<executions>
					<execution>
						<id>copy-resources</id>
						<phase>prepare-package</phase>
						<goals>
							<goal>copy-resources</goal>
						</goals>
						<configuration>
							<outputDirectory>
								${project.build.outputDirectory}/static/docs
							</outputDirectory> 
							<resources> 
								<resource>
									<directory>
										${project.build.directory}/generated-docs
									</directory>
								</resource>
							</resources>
						</configuration>
					</execution>
				</executions>
			</plugin>
		</plugins>
	</build>
</project>

 

4.  ๋„๋ฉ”์ธ๋ณ„๋กœ *.adoc ํŒŒ์ผ ๋‚˜๋ˆ ์„œ ๊ด€๋ฆฌํ•˜๊ธฐ

๋” ๋‚˜์•„๊ฐ€์„œ ๋„๋ฉ”์ธ ๋ณ„๋กœ *.adoc ํŒŒ์ผ๋“ค์„ ๋‚˜๋ˆ ์„œ ๊ด€๋ฆฌํ•˜๊ณ ์ž ํ•ฉ๋‹ˆ๋‹ค.

์™ผ์ชฝ) Maven์˜ .adoc ๋””๋ ‰ํ† ๋ฆฌ ๊ตฌ์กฐ / ์ค‘์•™) Gradle์˜ .adoc ๋””๋ ‰ํ† ๋ฆฌ ๊ตฌ์กฐ / ์˜ค๋ฅธ์ชฝ) HTML๊ฒฐ๊ณผ๋ฌผ ์œ„์น˜

 

Maven์€ src/main/asciidoc ํ•˜์œ„์— .adoc ํŒŒ์ผ์„ ๋‘๋Š” ๋ฐ˜๋ฉด, Gradle์€ src/docs/asciidoc์ฒ˜๋Ÿผ main๊ณผ๋Š” ๋‚˜๋ž€ํ•œ ๊ฒฝ๋กœ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฐ ์ฐจ์ด๋Š” ์•„๋ž˜ ์‚ฌ์ง„์ฒ˜๋Ÿผ Spring Rest Docs ๊ณต์‹ ๋ฌธ์„œ์—์„œ ๋นŒ๋“œ ํˆด๋ณ„๋กœ .adoc ํŒŒ์ผ์˜ ๊ธฐ๋ณธ ๊ตฌ์กฐ๋ฅผ ๋ช…์‹œํ•ด๋‘์—ˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

Spring Rest Docs 3.0.3 ์˜ *.adocํŒŒ์ผ๊ณผ *.html ์ƒ์„ฑ ํŒŒ์ผ ๊ธฐ๋ณธ ๊ฐ’

 

์•„๋ž˜๋Š” ๋„๋ฉ”์ธ ๋ณ„๋กœ ์ž‘์„ฑํ•œ *.adoc ํŒŒ์ผ์„ index.adoc์— include:: ๋ฌธ๋ฒ•์œผ๋กœ ํฌํ•จ์‹œํ‚ค๋Š” ์˜ˆ์‹œ์ž…๋‹ˆ๋‹ค.

= ๊ฒŒ์‹œํŒ API ๋ฌธ์„œ
:doctype: book
:icons: font
:source-highlighter: highlightjs
:toc: left
:toclevels: 2
:sectlinks:

== ๊ด€๋ฆฌ์ž API
include::admin/admin.adoc[]

== ๋Œ“๊ธ€ API
include::comment/comment.adoc[]

== ๊ฒŒ์‹œ๊ธ€ API
include::post/post.adoc[]

== ํšŒ์› API
include::user/user.adoc[]

 

๋„๋ฉ”์ธ๋ณ„๋กœ ๋‚˜๋ˆˆ ๋””๋ ‰ํ† ๋ฆฌ ๊ตฌ์กฐ๋ฅผ ๊ทธ๋Œ€๋กœ ๊ฒฐ๊ณผ๋ฌผ(target/generated-docs)์— ๋ฐ˜์˜ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด, <preserveDirectories> ํƒœ๊ทธ๋ฅผ true๋กœ ์„ค์ •ํ•ด์ค๋‹ˆ๋‹ค.

Asciidoctor์˜ <preserveDirectories>ํƒœ๊ทธ์— ๋Œ€ํ•œ ์„ค๋ช…

<configuration>
    <backend>html5</backend>
    <doctype>book</doctype>
    <!-- ์ถ”๊ฐ€! -->
    <preserveDirectories>true</preserveDirectories> <!-- ํ•ด๋‹น ํƒœ๊ทธ๋ฅผ ์ƒ๋žตํ•˜๋ฉด ๊ธฐ๋ณธ๊ฐ’ false ์ ์šฉ -->
</configuration>

๋‹ค๋งŒ, ์ €๋Š” ๋„๋ฉ”์ธ๋ณ„๋กœ ๊ฐ๊ฐ HTML ํŒŒ์ผ์„ ์ƒ์„ฑํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค๊ณ  ํŒ๋‹จํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ฒฐ๊ตญ ์‚ฌ์šฉ์ž ์ž…์žฅ์—์„œ๋Š” ํ•˜๋‚˜์˜ ๋ฌธ์„œ๋งŒ ๋ณด๋ฉด ๋˜๊ธฐ ๋•Œ๋ฌธ์—, index.adoc๋งŒ index.html๋กœ ๋ณ€ํ™˜๋˜๋ฉด ์ถฉ๋ถ„ํ•˜๋‹ค๊ณ  ํŒ๋‹จํ–ˆ์Šต๋‹ˆ๋‹ค.


๊ทธ๋ž˜์„œ <sourceDocumentName> ํƒœ๊ทธ๋ฅผ ํ™œ์šฉํ•ด ๋ณ€ํ™˜ํ•  ๋Œ€์ƒ์„ index.adoc ํ•˜๋‚˜๋กœ ๋ช…์‹œํ–ˆ์Šต๋‹ˆ๋‹ค.

Asciidoctor์—์„œ sourceDocumentName์€ ๊ธฐ๋ณธ์ ์œผ๋กœ sourceDirectory ๋‚ด์˜ ๋ชจ๋“  .adoc ํŒŒ์ผ์„ ์ฒ˜๋ฆฌํ•˜์ง€๋งŒ,
์ด ๊ฐ’์„ ์„ค์ •ํ•˜๋ฉด ํ•ด๋‹น ํŒŒ์ผ ํ•˜๋‚˜๋งŒ ์ฒ˜๋ฆฌ ๋Œ€์ƒ์œผ๋กœ ์ œํ•œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 

<sourceDocumentName> : ๊ธฐ๋ณธ๊ฐ’์€ ${sourceDirectory}์˜ ๋ชจ๋“  ํŒŒ์ผ์ž…๋‹ˆ๋‹ค. ${sourceDirectory}๋Š” asciidoctor ์˜ <sourceDirectory>ํƒœ๊ทธ๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค

<sourceDirectory> : ์†Œ์Šค ํŒŒ์ผ์ด ์œ„์น˜ํ•œ ๊ฒฝ๋กœ์ž…๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ ๋‹ค์Œ ๊ฒฝ๋กœ๋“ค์„ ์ˆœ์„œ๋Œ€๋กœ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
${basedir}/src/docs/asciidoc, ${basedir}/src/asciidoc, ${basedir}/src/main/asciidoc

 

Spring Rest Docs๋„ ์ด ๊ธฐ๋ณธ ๊ฒฝ๋กœ๋ฅผ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•˜๋ฏ€๋กœ, *.adoc ํŒŒ์ผ๋“ค์„ ์œ„ ๋””๋ ‰ํ† ๋ฆฌ์— ์œ„์น˜์‹œํ‚จ๋‹ค๋ฉด <sourceDirectory>๋ฅผ ๋”ฐ๋กœ ์„ค์ •ํ•  ํ•„์š”๋„ ์—†์Šต๋‹ˆ๋‹ค. ๊ฒฐ๊ณผ์ ์œผ๋กœ ์•„๋ž˜์™€ ๊ฐ™์€ ์„ค์ •๋งŒ ์ถ”๊ฐ€ํ•˜๋ฉด, ์ œ๊ฐ€ ์˜๋„ํ•œ ๋Œ€๋กœ index.adoc๋งŒ index.html๋กœ ๋ณ€ํ™˜๋ฉ๋‹ˆ๋‹ค.

<configuration>
    <backend>html5</backend>
    <doctype>book</doctype>
    <!-- ์ถ”๊ฐ€! -->
    <sourceDocumentName>index.adoc</sourceDocumentName>
</configuration>

 

๋” ๋‹ค์–‘ํ•œ Asciidoctor์˜ ํƒœ๊ทธ๋“ค์ด ๊ถ๊ธˆํ•˜์‹œ๋‹ค๋ฉด Asciidoctor Docs๋ฅผ ์ฐธ๊ณ ํ•ด์ฃผ์„ธ์š”.

 

์ด ํ›„, ์žฌ ๋นŒ๋“œํ•˜์—ฌ ๋นŒ๋“œ๊ฐ€ ์™„๋ฃŒ๋˜๋ฉด target/generated-docs ๋””๋ ‰ํ† ๋ฆฌ์— index.html ํŒŒ์ผ์ด ์ƒ์„ฑ๋˜๊ณ , ๊ทธ ์™ธ์— ๋„๋ฉ”์ธ ๋ณ„๋กœ ๊ตฌ์„ฑ๋œ ๋นˆ ๋””๋ ‰ํ† ๋ฆฌ๋“ค๋„ ํ•จ๊ป˜ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.

index.adoc๋งŒ index.html๋กœ ๋ณ€ํ™˜ํ•˜๊ธฐ

(์ €๋Š” ๋„๋ฉ”์ธ ๋ณ„ ๋น„์–ด์žˆ๋Š” ๋””๋ ‰ํ† ๋ฆฌ๋“ค์„ ์ œ๊ฑฐํ•˜๊ณ  ์‹ถ์–ด ์—ฌ๋Ÿฌ Asciidoctor ํƒœ๊ทธ๋“ค์„ ์‹œ๋„ํ•ด๋ดค์ง€๋งŒ, Gradle์—์„œ๋Š” ๊ฐ€๋Šฅํ–ˆ๋˜ ๋ฐ˜๋ฉด Maven์—์„œ๋Š” ๋šœ๋ ทํ•œ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์„ ์ฐพ์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค. ํ˜น์‹œ ์ด ๋ถ€๋ถ„์— ๋Œ€ํ•ด ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์„ ์•Œ๊ณ  ๊ณ„์‹  ๋ถ„์ด ์žˆ๋‹ค๋ฉด, ๋Œ“๊ธ€๋กœ ๊ณต์œ ํ•ด์ฃผ์‹œ๋ฉด ์ •๋ง ๊ฐ์‚ฌํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.)

 

๊ทธ๋ฆฌ๊ณ , target/generated-docs/index.html ํŒŒ์ผ์„ ์—ด์—ˆ์„ ๋•Œ ๋ฌธ์„œ๊ฐ€ ๊นจ์ง ์—†์ด ์ •์ƒ์ ์œผ๋กœ ๋ณด์ธ๋‹ค๋ฉด ์„ฑ๊ณต์ž…๋‹ˆ๋‹ค.

 

5. Windows ํ™˜๊ฒฝ์—์„œ ๊ฒฝ๋กœ ๊ตฌ๋ถ„ ๋ฌธ์ œ๋กœ ๋ฐœ์ƒํ•˜๋Š” Unresolved directive ์˜ค๋ฅ˜ ํ•ด๊ฒฐํ•˜๊ธฐ

Asciidoctor๋Š” ๋ฆฌ๋ˆ…์Šค ๊ธฐ๋ฐ˜์˜ ๊ฒฝ๋กœ ๊ตฌ๋ถ„ ๋ฐฉ์‹์„ ๋”ฐ๋ฅด๊ธฐ ๋•Œ๋ฌธ์—, ํŒŒ์ผ ๊ฒฝ๋กœ๋ฅผ /๋กœ ๊ตฌ๋ถ„ํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ Windows ํ™˜๊ฒฝ์—์„œ๋Š” \๋กœ ๊ฒฝ๋กœ๋ฅผ ๊ตฌ๋ถ„ํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ์•„๋ž˜์™€ ๊ฐ™์€ ๊ฒฝ๋กœ ์ธ์‹ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Unresolved directive in admin/admin.adoc - include::..\..\..\target\generated-snippets/admin

 

์ € ์—ญ์‹œ ์ด ๋ฌธ์ œ๋กœ ์ธํ•ด API ๋ฌธ์„œ๊ฐ€ ์ œ๋Œ€๋กœ ์ถœ๋ ฅ๋˜์ง€ ์•Š๋Š” ์ƒํ™ฉ์„ ๊ฒช์—ˆ์Šต๋‹ˆ๋‹ค. ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด, Asciidoctor์˜ snippets ๊ฒฝ๋กœ๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ์ง€์ •ํ•˜๊ณ  /๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์„ค์ •์„ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค.

<configuration>
    <backend>html5</backend>
    <doctype>book</doctype>
    <sourceDocumentName>index.adoc</sourceDocumentName>
    <!-- ์ถ”๊ฐ€! -->
    <attributes>
        <!-- snippet ์ƒ์„ฑ ์œ„์น˜ -->
        <snippets>${project.basedir}/target/generated-snippets</snippets>   
    </attributes>
</configuration>

${project.basedir} ์€ ํ˜„์žฌ ํ”„๋กœ์ ํŠธ๊ฐ€ ์žˆ๋Š” ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ${ ... } ๊ฐ™์ด Maven ์˜ POM ์†์„ฑ ๊ฐ’์€ Maven 3.9.9 ์—์„œ "project" ๋ž€ ๋ช…์นญ์œผ๋กœ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. POM ์†์„ฑ์— ๋Œ€ํ•ด ๋” ์•Œ์•„๋ณด๊ณ  ์‹ถ์œผ์‹  ๋ถ„๋“ค์„ ์œ„ํ•ด ์ฐธ๊ณ  ๋งํฌ ๊ฑธ์–ด๋‘๊ฒ ์Šต๋‹ˆ๋‹ค. Maven 3.9.9 - POM Reference

pom.xml์˜ project.basedir ์†์„ฑ์— ๋Œ€ํ•œ ์„ค๋ช…

 

6. ๋งˆ์น˜๋ฉฐ

Spring Rest Docs๋ฅผ ๋„์ž…ํ•˜๋ฉด์„œ pom.xml์— ํ•„์š”ํ•œ ์„ค์ •๋“ค์„ ๊ตฌ์„ฑํ•˜๋Š” ๊ณผ์ •์—์„œ, Maven ๊ณต์‹ ๋ฌธ์„œ์™€ Asciidoctor ๊ณต์‹ ๋ฌธ์„œ๋ฅผ ์ง์ ‘ ์ฐธ๊ณ ํ•˜๋ฉฐ ์ฐจ๊ทผ์ฐจ๊ทผ ์ดํ•ดํ•ด ๋‚˜๊ฐ”์Šต๋‹ˆ๋‹ค. ์ฒ˜์Œ Gradle๋กœ Rest Docs๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ๋Š” ๋นŒ๋“œ ํˆด ๋ฌธ๋ฒ•์— ๋Œ€ํ•œ ์ดํ•ด ์—†์ด

๊ทธ์ € ์˜ˆ์ œ๋ฅผ ๋”ฐ๋ผ๊ฐ€๊ธฐ์— ๋ฐ”๋นด๊ณ , ์„ค์ •์ด ์™œ ๊ทธ๋Ÿฐ ๊ตฌ์กฐ๋กœ ๋˜์–ด ์žˆ๋Š”์ง€ ๊นŠ์ด ๊ณ ๋ฏผํ•˜์ง€ ๋ชปํ–ˆ์—ˆ์Šต๋‹ˆ๋‹ค.


ํ•˜์ง€๋งŒ Maven์œผ๋กœ ๋‹ค์‹œ Rest Docs๋ฅผ ๋„์ž…ํ•˜๋ฉด์„œ, ๋นŒ๋“œ ํˆด์ด ๋‹ฌ๋ผ์กŒ๋‹ค๋Š” ์ด์œ  ํ•˜๋‚˜๋งŒ์œผ๋กœ๋„ ์˜ˆ์ƒ๋ณด๋‹ค ๋งŽ์€ ์‹œํ–‰์ฐฉ์˜ค๋ฅผ ๊ฒช๊ฒŒ ๋˜์—ˆ๊ณ , ๊ทธ ๊ณผ์ •์—์„œ ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ๋นŒ๋“œ ํˆด์˜ ๊ตฌ์กฐ์™€ ๋ฌธ๋ฒ•์„ ๊ณต๋ถ€ํ•˜๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

 

์ด ๊ฒฝํ—˜์„ ํ†ตํ•ด ํŠนํžˆ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ ์„ ๋ฐฐ์šธ ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค:

  • pom.xml์ด๋‚˜ build.gradle์— ๋“ค์–ด๊ฐ€๋Š” ์„ค์ •๊ฐ’๋“ค ์ค‘ ์–ด๋–ค ๊ฐ’์€ ํ”Œ๋Ÿฌ๊ทธ์ธ ๊ณต์‹ ๋ฌธ์„œ๋ฅผ ์ฐธ๊ณ ํ•ด์•ผ ํ•˜๊ณ , ์–ด๋–ค ๊ฐ’์€ ๋นŒ๋“œ ํˆด(Maven/Gradle)์˜ ๋ฌธ์„œ๋ฅผ ํ™•์ธํ•ด์•ผ ํ•˜๋Š”์ง€๋ฅผ ๊ตฌ๋ถ„ํ•˜๋Š” ๋ฐฉ๋ฒ•
  • ${project.build.outputDirectory} ์˜ Maven ์†์„ฑ ๊ฐ’์„ ๊ณต์‹๋ฌธ์„œ์—์„œ ํ™•์ธํ•˜๋Š” ๋ฐฉ๋ฒ•
  • jarํŒŒ์ผ์˜ ๊ฒฐ๊ณผ๋ฌผ์ด ์ปดํŒŒ์ผ๋œ .class ํŒŒ์ผ๊ณผ ๋ฆฌ์†Œ์Šค ํŒŒ์ผ๋“ค์„ ์••์ถ•ํ•œ ๊ฒƒ์ด๋ผ๋Š” ๊ฒƒ 

์ด์ œ ์•ž์œผ๋กœ ๋‹ค๋ฅธ ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์‚ฌ์šฉํ•  ๋•Œ๋„ ํ•„์š”ํ•œ ์„ค์ •์ด ๋ฌด์—‡์ธ์ง€, ๋˜ ์–ด๋–ค ๊ณต์‹ ๋ฌธ์„œ๋ฅผ ์ฐธ๊ณ ํ•ด์•ผ ํ•˜๋Š”์ง€๋ฅผ ๋ณด๋‹ค ๋น ๋ฅด๊ณ  ์ •ํ™•ํ•˜๊ฒŒ ํŒŒ์•…ํ•  ์ˆ˜ ์žˆ์„ ๊ฑฐ๋ผ ๊ธฐ๋Œ€ํ•ฉ๋‹ˆ๋‹ค.

 

์ฐธ๊ณ  ๋งํฌ๋กœ Maven์˜ pom.xml ์†์„ฑ ๋ฌธ์„œ์™€ Asciidoctor์˜ Maven ์„ค์ • ๋ฌธ์„œ๋ฅผ ํ•จ๊ป˜ ์ •๋ฆฌํ•ด๋‘์—ˆ์Šต๋‹ˆ๋‹ค.

Asciidoctor Docs

3.9.9 Maven Docs

Asciidoctor Maven Plugin Github