Skip to content

Commit 350ff9b

Browse files
authored
GH-232 Allow reference to a model from OpenApiContentProperty (#232)
* allow reference to a model from OpenApiContentProperty * add test for recursive class
1 parent cff4deb commit 350ff9b

File tree

6 files changed

+41
-14
lines changed

6 files changed

+41
-14
lines changed

examples/javalin-gradle-kotlin/src/main/java/io/javalin/openapi/plugin/test/JavalinTest.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,7 @@ public static void main(String[] args) {
203203
@OpenApiContent(mimeType = "image/png", type = "string", format = "base64"), // single file upload,
204204
@OpenApiContent(mimeType = "multipart/form-data", properties = {
205205
@OpenApiContentProperty(name = "form-element", type = "integer"), // random element in form-data
206+
@OpenApiContentProperty(name = "reference", from = KotlinEntity.class), // reference to another object
206207
@OpenApiContentProperty(name = "file-name", isArray = true, type = "string", format = "base64") // multi-file upload
207208
})
208209
}

examples/javalin-maven-java/src/main/java/io/javalin/openapi/plugin/test/JavalinTest.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ public static void main(String[] args) {
175175
@OpenApiContent(mimeType = "image/png", type = "string", format = "base64"), // single file upload,
176176
@OpenApiContent(mimeType = "multipart/form-data", properties = {
177177
@OpenApiContentProperty(name = "form-element", type = "integer"), // random element in form-data
178+
@OpenApiContentProperty(name = "reference", from = KotlinEntity.class) // reference to another object
178179
@OpenApiContentProperty(name = "file-name", isArray = true, type = "string", format = "base64") // multi-file upload
179180
})
180181
}

openapi-annotation-processor/src/main/kotlin/io/javalin/openapi/processor/generators/OpenApiGenerator.kt

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -444,22 +444,29 @@ internal class OpenApiGenerator {
444444
schema.addProperty("type", "object")
445445

446446
for (contentProperty in properties) {
447-
val propertyScheme = JsonObject()
448447
val propertyFormat = contentProperty.format.takeIf { it != NULL_STRING }
449448

450-
if (contentProperty.isArray) {
451-
propertyScheme.addProperty("type", "array")
452-
453-
val items = JsonObject()
454-
items.addProperty("type", contentProperty.type)
455-
propertyFormat?.let { items.addProperty("format", it) }
456-
propertyScheme.add("items", items)
449+
val contentPropertyFrom = contentAnnotation.getTypeMirror { contentProperty.from }
450+
val propertyScheme = if (contentPropertyFrom.getFullName() != NULL_CLASS::class.java.name) {
451+
createTypeDescriptionWithReferences(contentPropertyFrom)
457452
} else {
458-
propertyScheme.addProperty("type", contentProperty.type)
459-
propertyFormat?.let { propertyScheme.addProperty("format", it) }
453+
JsonObject().apply {
454+
addProperty("type", contentProperty.type)
455+
propertyFormat?.let { addProperty("format", it) }
456+
}
460457
}
461458

462-
propertiesSchema.add(contentProperty.name, propertyScheme)
459+
propertiesSchema.add(contentProperty.name,
460+
if (contentProperty.isArray) {
461+
// wrap into OpenAPI array object
462+
JsonObject().apply {
463+
addProperty("type", "array")
464+
add("items", propertyScheme)
465+
}
466+
} else {
467+
propertyScheme
468+
}
469+
)
463470
}
464471

465472
schema.add("properties", propertiesSchema)

openapi-annotation-processor/src/test/kotlin/io/javalin/openapi/processor/TypeMappersTest.kt

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,4 +197,21 @@ internal class TypeMappersTest : OpenApiAnnotationProcessorSpecification() {
197197
))
198198
}
199199

200-
}
200+
private class Loop(
201+
val self: Loop?,
202+
)
203+
204+
205+
@OpenApi(
206+
path = "recursive",
207+
versions = ["should_map_recursive_type"],
208+
responses = [OpenApiResponse(status = "200", content = [OpenApiContent(from = Loop::class)])]
209+
)
210+
@Test
211+
fun should_map_recursive_type() = withOpenApi("should_map_recursive_type") {
212+
assertThatJson(it)
213+
.inPath("$.components.schemas.Loop.properties.self")
214+
.isObject
215+
.containsEntry("\$ref", "#/components/schemas/Loop")
216+
}
217+
}

openapi-specification/src/main/kotlin/io/javalin/openapi/OpenApiAnnotations.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,9 +147,10 @@ annotation class OpenApiContent(
147147
@Target()
148148
@Retention(RUNTIME)
149149
annotation class OpenApiContentProperty(
150+
val from: KClass<*> = NULL_CLASS::class,
150151
val name: String,
151152
val isArray: Boolean = false,
152-
val type: String,
153+
val type: String = NULL_STRING,
153154
val format: String = NULL_STRING
154155
)
155156

wiki

Submodule wiki updated from bffdf4c to 204546a

0 commit comments

Comments
 (0)