Last active
July 2, 2022 14:06
-
-
Save eungju/7ed0e5b0c5090b41f1666c3786b1ba4d to your computer and use it in GitHub Desktop.
Spring REST Docs Kotlin DSL
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import org.springframework.restdocs.headers.HeaderDescriptor | |
import org.springframework.restdocs.headers.HeaderDocumentation | |
import org.springframework.restdocs.mockmvc.MockMvcRestDocumentation | |
import org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessResponse | |
import org.springframework.restdocs.operation.preprocess.Preprocessors.prettyPrint | |
import org.springframework.restdocs.payload.FieldDescriptor | |
import org.springframework.restdocs.payload.PayloadDocumentation | |
import org.springframework.restdocs.payload.SubsectionDescriptor | |
import org.springframework.restdocs.request.ParameterDescriptor | |
import org.springframework.restdocs.request.RequestDocumentation | |
import org.springframework.restdocs.snippet.Snippet | |
import org.springframework.test.web.servlet.ResultActionsDsl | |
class DocumentScope { | |
internal val snippets = mutableListOf<Snippet>() | |
abstract class HttpMessageScope { | |
internal val headerDescriptors = mutableListOf<HeaderDescriptor>() | |
internal val fieldDescriptors = mutableListOf<FieldDescriptor>() | |
fun header(name: String): HeaderDescriptor = | |
HeaderDocumentation.headerWithName(name) | |
.also { headerDescriptors.add(it) } | |
fun field(path: String): FieldDescriptor = | |
PayloadDocumentation.fieldWithPath(path) | |
.also { fieldDescriptors.add(it) } | |
fun subsection(path: String): SubsectionDescriptor = | |
PayloadDocumentation.subsectionWithPath(path) | |
.also { fieldDescriptors.add(it) } | |
} | |
class RequestScope : HttpMessageScope() { | |
internal val parameterDescriptors = mutableListOf<ParameterDescriptor>() | |
fun parameter(name: String): ParameterDescriptor = | |
RequestDocumentation.parameterWithName(name) | |
.also { parameterDescriptors.add(it) } | |
} | |
fun request(configure: RequestScope.() -> Unit) { | |
val scope = RequestScope().apply(configure) | |
scope.parameterDescriptors.let { | |
if (it.isNotEmpty()) { | |
snippets.add(RequestDocumentation.requestParameters(it)) | |
} | |
} | |
scope.headerDescriptors.let { | |
if (it.isNotEmpty()) { | |
snippets.add(HeaderDocumentation.requestHeaders(it)) | |
} | |
} | |
scope.fieldDescriptors.let { | |
if (it.isNotEmpty()) { | |
snippets.add(PayloadDocumentation.requestFields(it)) | |
} | |
} | |
} | |
class ResponseScope : HttpMessageScope() | |
fun response(configure: ResponseScope.() -> Unit) { | |
val scope = ResponseScope().apply(configure) | |
scope.headerDescriptors.let { | |
if (it.isNotEmpty()) { | |
snippets.add(HeaderDocumentation.responseHeaders(it)) | |
} | |
} | |
scope.fieldDescriptors.let { | |
if (it.isNotEmpty()) { | |
snippets.add(PayloadDocumentation.responseFields(it)) | |
} | |
} | |
} | |
} | |
fun ResultActionsDsl.andDocument( | |
identifier: String, | |
configure: DocumentScope.() -> Unit | |
): ResultActionsDsl = | |
andDo { | |
val scope = DocumentScope().apply(configure) | |
handle( | |
MockMvcRestDocumentation.document( | |
identifier, | |
preprocessResponse(prettyPrint()), | |
*scope.snippets.toTypedArray() | |
) | |
) | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
mockMvc | |
.get("/search") { | |
param("q", keyword) | |
client() | |
} | |
.andExpect { | |
status { isOk } | |
content { contentType(MediaType.APPLICATION_JSON) } | |
} | |
.andDocument("/search/GET") { | |
request { | |
parameter("q") | |
.description("검색 키워드") | |
clientHeaders() | |
header("Referer") | |
.optional() | |
.description("리퍼러") | |
} | |
response { | |
field("items") | |
.type(JsonFieldType.ARRAY) | |
.description("아이템들.") | |
subsection("items[].title") | |
.type(JsonFieldType.STRING) | |
.description("제목.") | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment