https://github.com/keecon/restdocs-openapi3
Clone of ePages-de/restdocs-api-spec with class field type and constraint inference.
https://github.com/keecon/restdocs-openapi3
openapi3 spring spring-boot spring-rest-docs
Last synced: 6 months ago
JSON representation
Clone of ePages-de/restdocs-api-spec with class field type and constraint inference.
- Host: GitHub
- URL: https://github.com/keecon/restdocs-openapi3
- Owner: keecon
- License: mit
- Created: 2022-02-22T03:33:26.000Z (over 4 years ago)
- Default Branch: main
- Last Pushed: 2025-04-22T02:24:43.000Z (about 1 year ago)
- Last Synced: 2025-04-22T04:12:52.200Z (about 1 year ago)
- Topics: openapi3, spring, spring-boot, spring-rest-docs
- Language: Kotlin
- Homepage:
- Size: 526 KB
- Stars: 2
- Watchers: 4
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
- Codeowners: .github/CODEOWNERS
Awesome Lists containing this project
README
# Spring REST Docs OpenAPI 3 Specification
[![jitpack-badge]](https://jitpack.io/#keecon/restdocs-openapi3)
[![build-badge]](https://github.com/keecon/restdocs-openapi3/actions/workflows/build.yml)
[![codecov-badge]](https://codecov.io/gh/keecon/restdocs-openapi3)
[![sonarcloud-badge]](https://sonarcloud.io/summary/new_code?id=keecon_restdocs-openapi3)
[![license-badge]](https://github.com/keecon/restdocs-openapi3/blob/main/LICENSE)
A modified version of the [ePages-de/restdocs-api-spec] with class field type and constraint inference.
And only support [OpenAPI 3.0.1] specs.
## Build configuration
### Versions
- The *1.x.x* version is compatible with Spring Boot *3.0.x* and Spring REST Docs *3.0.x*.
- The *0.x.x* version is compatible with Spring Boot *2.7.x* and Spring REST Docs *2.0.x*.
### Gradle
1. Add the plugin
```groovy
buildscript() {
repositories {
// ...
maven { url "https://jitpack.io" }
}
dependencies {
// ...
classpath 'com.github.keecon:restdocs-openapi3:x.x.x'
}
}
plugins {
// ...
id 'com.github.keecon:restdocs-openapi3'
}
```
2. Add required dependencies to your tests
```groovy
repositories {
// ...
maven { url 'https://jitpack.io' }
}
dependencies {
//..
testImplementation 'com.github.keecon:restdocs-openapi3:x.x.x'
}
openapi3 {
server = 'http://localhost:8080'
title = 'My API'
description = 'My API description'
tagDescriptionsPropertiesFile = 'src/test/resources/openapi-tags.yml'
version = '0.1.0'
format = 'yaml'
}
```
## Usage with Spring REST Docs
```groovy
when:
def resultActions = mockMvc.perform(
post('/v1/products/{productId}/result', 1)
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsBytes(new ProductResultCreateRequestBody(result)))
.accept(MediaType.APPLICATION_JSON)
)
then:
def reqModel = Constraints.model(ProductResultCreateRequest.class)
def reqBodyModel = Constraints.model(ProductResultCreateRequestBody.class)
def respModel = Constraints.model(ProductResultCreateResponse.class)
resultActions
.andExpect(status().isOk())
.andDo(document('products-id-result-post',
resource(ResourceSnippetParameters.builder()
.tag('product')
.summary('Create a product result')
.description('''
|Create a product result
|
|### Error details
|
|`400` BAD_REQUEST
|- bad request description
|
|`401` UNAUTHORIZED
|- unauthorized description
|
|'''.stripMargin())
.requestSchema(schema('ProductResultCreateRequest'))
.pathParameters(
reqModel.withName('productId').description('product id'),
)
.requestFields(
reqBodyModel.withPath('result').description('product result'),
reqBodyModel.withPath('result.code').description('product result code'),
reqBodyModel.withPath('result.seq').description('product result seq'),
reqBodyModel.withPath('result.score').description('product result score'),
reqBodyModel.withPath('result.assigns[]').description('result assign object list'),
reqBodyModel.withPath('result.assigns[].code').description('result assign code'),
reqBodyModel.withPath('result.assigns[].seq').description('result assign seq'),
reqBodyModel.withPath('result.assigns[].objectId').description('result assign object id'),
reqBodyModel.withPath('result.assigns[].fileType').description('result assign file type')
.optional(),
reqBodyModel.withPath('result.assigns[].fileUrl').description('result assign file url')
.optional(),
reqBodyModel.withPath('result.assigns[].comments[]').description('result assign comment list')
.type(DataType.ARRAY)
.attributes(Attributes.items(DataType.STRING, null, null))
.optional(),
)
.responseSchema(schema('ProductResultCreateResponse'))
.responseFields(
respModel.withPath('status').description('operation status'),
respModel.withPath('code').description('product result code')
.optional(),
)
.build())))
```
```groovy
when:
def resultActions = mockMvc.perform(
get('/v1/products/{productId}/result?code={code}', 1, 1)
.accept(MediaType.APPLICATION_JSON)
)
then:
def reqModel = Constraints.model(ProductResultRequest.class)
def respModel = Constraints.model(ProductResultResponse.class)
resultActions
.andExpect(status().isOk())
.andDo(document('products-id-result-code-get',
resource(ResourceSnippetParameters.builder()
.tag('product')
.summary('Get a product result info')
.description('''
|Get a product result info
|
|### Error details
|
|`400` BAD_REQUEST
|- bad request description
|
|`401` UNAUTHORIZED
|- unauthorized description
|
|`404` NOT_FOUND
|- not found description
|
|'''.stripMargin())
.requestSchema(schema('ProductResultRequest'))
.pathParameters(
reqModel.withName('productId').description('product id'),
)
.queryParameters(
reqModel.withName('code').description('product result code'),
reqModel.withName('seq').description('product result seq')
.defaultValue(ProductResultRequest.DEFAULT_RESULT_SEQ)
.optional(),
)
.responseSchema(schema('ProductResultResponse'))
.responseFields(
respModel.withPath('result').description('product result'),
respModel.withPath('result.code').description('product result code'),
respModel.withPath('result.seq').description('product result seq'),
respModel.withPath('result.score').description('product result score'),
respModel.withPath('result.assigns[]').description('result assign object list'),
respModel.withPath('result.assigns[].code').description('result assign code'),
respModel.withPath('result.assigns[].seq').description('result assign seq'),
respModel.withPath('result.assigns[].objectId').description('result assign object id'),
respModel.withPath('result.assigns[].fileType').description('result assign file type')
.optional(),
respModel.withPath('result.assigns[].fileUrl').description('result assign file url')
.optional(),
respModel.withPath('result.assigns[].comments[]').description('result assign comment list')
.type(DataType.ARRAY)
.attributes(Attributes.items(DataType.STRING, null, null))
.optional(),
)
.build())))
```
[jitpack-badge]: https://jitpack.io/v/keecon/restdocs-openapi3.svg
[build-badge]: https://github.com/keecon/restdocs-openapi3/actions/workflows/build.yml/badge.svg
[codecov-badge]: https://codecov.io/gh/keecon/restdocs-openapi3/branch/main/graph/badge.svg?token=TRQZ6GOVK4
[sonarcloud-badge]: https://sonarcloud.io/api/project_badges/measure?project=keecon_restdocs-openapi3&metric=alert_status
[license-badge]: https://img.shields.io/github/license/keecon/restdocs-openapi3.svg
[ePages-de/restdocs-api-spec]: https://github.com/ePages-de/restdocs-api-spec
[OpenAPI 3.0.1]: https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.1.md