-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[feat] Rest Docs 적용 #73
Changes from 5 commits
d1b5b10
8105efb
8ec970a
bf891da
3ff0a61
b1da48e
af72ded
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
HELP.md | ||
.gradle | ||
build/ | ||
!gradle/wrapper/gradle-wrapper.jar | ||
!**/src/main/**/build/ | ||
!**/src/test/**/build/ | ||
|
||
### STS ### | ||
.apt_generated | ||
.classpath | ||
.factorypath | ||
.project | ||
.settings | ||
.springBeans | ||
.sts4-cache | ||
bin/ | ||
!**/src/main/**/bin/ | ||
!**/src/test/**/bin/ | ||
|
||
### IntelliJ IDEA ### | ||
.idea | ||
*.iws | ||
*.iml | ||
*.ipr | ||
out/ | ||
!**/src/main/**/out/ | ||
!**/src/test/**/out/ | ||
|
||
### NetBeans ### | ||
/nbproject/private/ | ||
/nbbuild/ | ||
/dist/ | ||
/nbdist/ | ||
/.nb-gradle/ | ||
|
||
### rest docs ### | ||
/src/main/resources/static/docs | ||
|
||
### VS Code ### | ||
.vscode/ | ||
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,7 @@ plugins { | |
id 'java' | ||
id 'org.springframework.boot' version '3.2.0' | ||
id 'io.spring.dependency-management' version '1.1.4' | ||
id "org.asciidoctor.jvm.convert" version "3.3.2" | ||
} | ||
|
||
group = 'com.kernel360' | ||
|
@@ -11,7 +12,12 @@ java { | |
sourceCompatibility = '17' | ||
} | ||
|
||
ext { | ||
snippetsDir = file('build/generated-snippets') | ||
} | ||
|
||
configurations { | ||
asciidoctorExt | ||
compileOnly { | ||
extendsFrom annotationProcessor | ||
} | ||
|
@@ -30,32 +36,63 @@ dependencies { | |
implementation 'org.springframework.boot:spring-boot-starter-aop' | ||
implementation 'org.springframework.boot:spring-boot-starter-data-jpa' | ||
//implementation 'org.springframework.boot:spring-boot-starter-security' | ||
|
||
// jasypt | ||
implementation 'com.github.ulisesbocchio:jasypt-spring-boot-starter:3.0.5' | ||
|
||
// flyway | ||
implementation 'org.flywaydb:flyway-core' | ||
|
||
// postgresql | ||
runtimeOnly 'org.postgresql:postgresql' | ||
|
||
//lombok | ||
compileOnly 'org.projectlombok:lombok' | ||
annotationProcessor 'org.projectlombok:lombok' | ||
testCompileOnly 'org.projectlombok:lombok' | ||
testAnnotationProcessor 'org.projectlombok:lombok' | ||
|
||
// validataion | ||
implementation 'org.springframework.boot:spring-boot-starter-validation:2.7.4' | ||
|
||
// test | ||
testImplementation 'org.springframework.boot:spring-boot-starter-test' | ||
testImplementation 'org.springframework.security:spring-security-test' | ||
|
||
// test - fixture Monkey | ||
testImplementation 'net.jqwik:jqwik:1.7.3' | ||
testImplementation("com.navercorp.fixturemonkey:fixture-monkey-starter:1.0.0") | ||
testImplementation("com.navercorp.fixturemonkey:fixture-monkey-jakarta-validation:1.0.0") | ||
|
||
// rest docs | ||
testImplementation 'org.springframework.restdocs:spring-restdocs-mockmvc' | ||
asciidoctorExt 'org.springframework.restdocs:spring-restdocs-asciidoctor' | ||
} | ||
|
||
tasks.named('test') { | ||
outputs.dir snippetsDir | ||
useJUnitPlatform() | ||
} | ||
|
||
tasks.register("prepareKotlinBuildScriptModel") {} | ||
asciidoctor { | ||
dependsOn test | ||
configurations 'asciidoctorExt' | ||
baseDirFollowsSourceFile() | ||
inputs.dir snippetsDir | ||
} | ||
|
||
asciidoctor.doFirst { | ||
delete file('src/main/resources/static/docs') | ||
} | ||
|
||
task copyDocument(type: Copy) { | ||
dependsOn asciidoctor | ||
from file("build/docs/asciidoc") | ||
into file("src/main/resources/static/docs") | ||
} | ||
|
||
bootJar { | ||
dependsOn copyDocument | ||
} | ||
|
||
tasks.register("prepareKotlinBuildScriptModel") {} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here are some findings and suggestions for the code patch:
Overall, these changes improve the build process and ensure that the latest documentation is included in the application's distribution. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
= API Document | ||
:doctype: book | ||
:icons: font | ||
:source-highlighter: highlightjs | ||
:toc: left | ||
:toclevels: 2 | ||
:sectlinks: | ||
|
||
include::overview.adoc[] | ||
include::sample-api.adoc[] | ||
// !!! 위 라인 1줄은 추후 삭제 예정입니다 !!! |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
[[overview]] | ||
== Overview | ||
|
||
[[overview-host]] | ||
=== Domain | ||
|
||
[cols="3,7"] | ||
|=== | ||
| 환경 | Domain | ||
| 개발 서버 | ||
| `http://washpedia.my-project.life` | ||
| 운영 서버 | ||
| | ||
|=== |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
// !!! 삭제 예정 파일입니다 !!! | ||
== 샘플 API | ||
|
||
// [[]] 안에는 a 태그 이름 들어갑니다 (http://localhost:8080/docs/index#공통코드-조회) | ||
[[공통코드-조회]] | ||
=== 공통코드 조회 | ||
|
||
// [Request] 실제로 API 에서 필요한 내용들만 아래 내용을 추가합니다 | ||
==== Request | ||
include::{snippets}/commoncode/get-common-codes/path-parameters.adoc[] | ||
// include::{snippets}/commoncode/get-common-codes/query-parameters.adoc[] | ||
// include::{snippets}/commoncode/get-common-codes/request-fields.adoc[] | ||
|
||
===== HTTP Request 예시 | ||
include::{snippets}/commoncode/get-common-codes/http-request.adoc[] | ||
|
||
// [Response] 실제로 API 에서 필요한 내용들만 아래 내용을 추가합니다 | ||
==== Response | ||
// include::{snippets}/commoncode/get-common-codes/response-fields.adoc[] | ||
include::{snippets}/commoncode/get-common-codes/response-fields-value.adoc[] | ||
|
||
===== HTTP Response 예시 | ||
include::{snippets}/commoncode/get-common-codes/http-response.adoc[] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package com.kernel360.common; | ||
|
||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
import com.kernel360.commoncode.controller.CommonCodeController; | ||
import com.kernel360.commoncode.service.CommonCodeService; | ||
import com.kernel360.member.controller.MemberController; | ||
import com.kernel360.member.service.MemberService; | ||
import com.kernel360.product.controller.ProductController; | ||
import com.kernel360.product.service.ProductService; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs; | ||
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; | ||
import org.springframework.boot.test.mock.mockito.MockBean; | ||
import org.springframework.test.web.servlet.MockMvc; | ||
|
||
@WebMvcTest({ | ||
CommonCodeController.class, | ||
MemberController.class, | ||
ProductController.class | ||
}) | ||
@AutoConfigureRestDocs | ||
public abstract class ControllerTest { | ||
|
||
@Autowired | ||
protected MockMvc mockMvc; | ||
|
||
@Autowired | ||
protected ObjectMapper objectMapper; | ||
|
||
@MockBean | ||
protected CommonCodeService commonCodeService; | ||
|
||
@MockBean | ||
protected MemberService memberService; | ||
|
||
@MockBean | ||
protected ProductService productService; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package com.kernel360.common.utils; | ||
|
||
import org.springframework.restdocs.operation.preprocess.OperationRequestPreprocessor; | ||
import org.springframework.restdocs.operation.preprocess.OperationResponsePreprocessor; | ||
|
||
import static org.springframework.restdocs.operation.preprocess.Preprocessors.*; | ||
|
||
public interface RestDocumentUtils { | ||
|
||
static OperationRequestPreprocessor getDocumentRequest() { | ||
return preprocessRequest(modifyUris().scheme("http") | ||
.host("washpedia.my-project.life") | ||
.removePort(), prettyPrint()); | ||
} | ||
|
||
static OperationResponsePreprocessor getDocumentResponse() { | ||
return preprocessResponse(prettyPrint()); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
package com.kernel360.commoncode.controller; | ||
|
||
import com.kernel360.common.ControllerTest; | ||
import com.kernel360.commoncode.dto.CommonCodeDto; | ||
import org.junit.jupiter.api.Test; | ||
import org.springframework.restdocs.payload.JsonFieldType; | ||
import org.springframework.test.web.servlet.ResultActions; | ||
|
||
import java.time.LocalDate; | ||
import java.util.Arrays; | ||
import java.util.List; | ||
|
||
import static com.kernel360.common.utils.RestDocumentUtils.getDocumentRequest; | ||
import static com.kernel360.common.utils.RestDocumentUtils.getDocumentResponse; | ||
import static org.mockito.BDDMockito.given; | ||
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; | ||
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get; | ||
import static org.springframework.restdocs.payload.PayloadDocumentation.*; | ||
import static org.springframework.restdocs.request.RequestDocumentation.*; | ||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; | ||
|
||
// !!! 삭제 예정 파일입니다 !!! | ||
class CommonCodeControllerRestDocsTest extends ControllerTest { | ||
|
||
@Test | ||
void commmonCodeSearch() throws Exception { | ||
//given | ||
List<CommonCodeDto> responseList = Arrays.asList( | ||
CommonCodeDto.of( | ||
11L, | ||
"Sedan", | ||
10, | ||
"cartype", | ||
1, | ||
true, | ||
"세단", | ||
LocalDate.now(), | ||
"admin", | ||
null, | ||
null), | ||
CommonCodeDto.of( | ||
12L, | ||
"Hatchback", | ||
10, | ||
"cartype", | ||
2, | ||
true, | ||
"해치백", | ||
LocalDate.now(), | ||
"admin", | ||
null, | ||
null) | ||
); | ||
|
||
String pathVariable = "color"; | ||
given(commonCodeService.getCodes(pathVariable)).willReturn(responseList); | ||
|
||
|
||
//when | ||
ResultActions result = this.mockMvc.perform( | ||
get("/commoncode/test/{codeName}", pathVariable)); | ||
|
||
|
||
//then | ||
//pathParameters, pathParameters, requestFields, responseFields는 필요 시 각각 작성 | ||
result.andExpect(status().isOk()) | ||
.andDo(document( | ||
"commoncode/get-common-codes", | ||
getDocumentRequest(), | ||
getDocumentResponse(), | ||
pathParameters( | ||
parameterWithName("codeName").description("코드명") | ||
), | ||
// pathParameters( | ||
// parameterWithName("size").description("size").optional(), | ||
// parameterWithName("page").description("page").optional() | ||
// ), | ||
// requestFields( | ||
// fieldWithPath("codeName").type(JsonFieldType.STRING).description("코드명"), | ||
// fieldWithPath("upperName").type(JsonFieldType.STRING).description("상위 코드명").optional() | ||
// ), | ||
// responseFields( | ||
// fieldWithPath("codeNo").type(JsonFieldType.NUMBER).description("코드번호"), | ||
// ) | ||
responseFields(beneathPath("value").withSubsectionId("value"), | ||
fieldWithPath("codeNo").type(JsonFieldType.NUMBER).description("코드번호"), | ||
fieldWithPath("codeName").type(JsonFieldType.STRING).description("코드명"), | ||
fieldWithPath("upperNo").type(JsonFieldType.NUMBER).description("상위 코드번호").optional(), | ||
fieldWithPath("upperName").type(JsonFieldType.STRING).description("상위 코드명").optional(), | ||
fieldWithPath("sortOrder").type(JsonFieldType.NUMBER).description("정렬순서"), | ||
fieldWithPath("isUsed").type(JsonFieldType.BOOLEAN).description("사용여부"), | ||
fieldWithPath("description").type(JsonFieldType.STRING).description("설명"), | ||
fieldWithPath("createdAt").type(JsonFieldType.STRING).description("생성일시"), | ||
fieldWithPath("createdBy").type(JsonFieldType.STRING).description("생성자"), | ||
fieldWithPath("modifiedAt").type(JsonFieldType.STRING).description("수정일시").optional(), | ||
fieldWithPath("modifiedBy").type(JsonFieldType.STRING).description("수정자").optional() | ||
) | ||
)); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
===== End Point | ||
{{path}} | ||
|
||
===== Path Parameters | ||
|=== | ||
|
||
|파라미터|설명 | ||
|
||
{{#parameters}} | ||
|{{#tableCellContent}}`+{{name}}+`{{/tableCellContent}} | ||
|{{#tableCellContent}}{{description}}{{/tableCellContent}} | ||
{{/parameters}} | ||
|
||
|=== |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code patch you provided seems to be a
.gitignore
file. It specifies the files and directories that should be ignored by Git when tracking changes in a project. Here are some observations and suggestions based on the provided patch:It's generally a good practice to include a top-level directory, such as the project root, before specifying individual files and directories to ignore. This ensures that the
.gitignore
rules apply correctly to the entire project.The
HELP.md
file is mentioned at the beginning of the patch. If this file is meant to be ignored, it should be removed from version control. Otherwise, it will continue to be tracked.The exclusion patterns using
!
(e.g.,!**/src/main/**/build/
) are intended to override previous ignore patterns and include specific files or directories. Make sure these patterns align with your project structure and desired behavior.It's recommended to exclude generated build artifacts like
build/
,bin/
, andout/
directories to avoid including compiled files in version control. However, be cautious when applying such exclusions to ensure necessary build configuration files are not inadvertently ignored.Integrated development environment (IDE)-specific directories and files like
.gradle
,.idea
, and.vscode/
are excluded. This assumes that developers using different IDEs will generate their own specific configuration files without affecting the core project.The
*/src/main/*/out/
and*/src/test/*/out/
patterns suggest excluding specific output directories from source directories that may contain generated files. This can be helpful to avoid including intermediate build results.The
/src/main/resources/static/docs
directory is included, implying that its contents should be tracked in version control. Ensure this matches the intended behavior; otherwise, if the documentation is dynamically generated or updated during builds, it may be better to exclude it.Remember to periodically review and update your
.gitignore
file as the project evolves and new files or build artifacts are introduced. Additionally, consider collaborating with other developers on the project to fine-tune the ignore rules based on their respective development environments and tools.