Support polymorphic collections and maps (#82)
This commit is contained in:
@ -1,5 +1,11 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## [1.5.1] - August 12th, 2021
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Fixed bug where polymorphic types were not being rendered correctly when part of collections and maps
|
||||||
|
|
||||||
## [1.5.0] - July 25th, 2021
|
## [1.5.0] - July 25th, 2021
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
# Kompendium
|
# Kompendium
|
||||||
project.version=1.5.0
|
project.version=1.5.1
|
||||||
# Kotlin
|
# Kotlin
|
||||||
kotlin.code.style=official
|
kotlin.code.style=official
|
||||||
# Gradle
|
# Gradle
|
||||||
|
@ -49,23 +49,8 @@ object KompendiumPreFlight {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun addToCache(paramType: KType, requestType: KType, responseType: KType) {
|
fun addToCache(paramType: KType, requestType: KType, responseType: KType) {
|
||||||
gatherSubTypes(requestType).forEach {
|
Kompendium.cache = Kontent.generateKontent(requestType, Kompendium.cache)
|
||||||
Kompendium.cache = Kontent.generateKontent(it, Kompendium.cache)
|
Kompendium.cache = Kontent.generateKontent(responseType, Kompendium.cache)
|
||||||
}
|
|
||||||
gatherSubTypes(responseType).forEach {
|
|
||||||
Kompendium.cache = Kontent.generateKontent(it, Kompendium.cache)
|
|
||||||
}
|
|
||||||
Kompendium.cache = Kontent.generateParameterKontent(paramType, Kompendium.cache)
|
Kompendium.cache = Kontent.generateParameterKontent(paramType, Kompendium.cache)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun gatherSubTypes(type: KType): List<KType> {
|
|
||||||
val classifier = type.classifier as KClass<*>
|
|
||||||
return if (classifier.isSealed) {
|
|
||||||
classifier.sealedSubclasses.map {
|
|
||||||
it.createType(type.arguments)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
listOf(type)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,22 @@ object Kontent {
|
|||||||
type: KType,
|
type: KType,
|
||||||
cache: SchemaMap = emptyMap()
|
cache: SchemaMap = emptyMap()
|
||||||
): SchemaMap {
|
): SchemaMap {
|
||||||
return generateKTypeKontent(type, cache)
|
var newCache = cache
|
||||||
|
gatherSubTypes(type).forEach {
|
||||||
|
newCache = generateKTypeKontent(it, newCache)
|
||||||
|
}
|
||||||
|
return newCache
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun gatherSubTypes(type: KType): List<KType> {
|
||||||
|
val classifier = type.classifier as KClass<*>
|
||||||
|
return if (classifier.isSealed) {
|
||||||
|
classifier.sealedSubclasses.map {
|
||||||
|
it.createType(type.arguments)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
listOf(type)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -220,11 +235,20 @@ object Kontent {
|
|||||||
if (keyType?.classifier != String::class) {
|
if (keyType?.classifier != String::class) {
|
||||||
error("Invalid Map $type: OpenAPI dictionaries must have keys of type String")
|
error("Invalid Map $type: OpenAPI dictionaries must have keys of type String")
|
||||||
}
|
}
|
||||||
val valClassName = (valType?.classifier as KClass<*>).simpleName
|
val valClass = valType?.classifier as KClass<*>
|
||||||
|
val valClassName = valClass.simpleName
|
||||||
val referenceName = genericNameAdapter(type, clazz)
|
val referenceName = genericNameAdapter(type, clazz)
|
||||||
val valueReference = ReferencedSchema("$COMPONENT_SLUG/$valClassName")
|
val valueReference = when(valClass.isSealed) {
|
||||||
|
true -> {
|
||||||
|
val subTypes = gatherSubTypes(valType)
|
||||||
|
AnyOfReferencedSchema(subTypes.map {
|
||||||
|
ReferencedSchema(("$COMPONENT_SLUG/${it.getSimpleSlug()}"))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
false -> ReferencedSchema("$COMPONENT_SLUG/$valClassName")
|
||||||
|
}
|
||||||
val schema = DictionarySchema(additionalProperties = valueReference)
|
val schema = DictionarySchema(additionalProperties = valueReference)
|
||||||
val updatedCache = generateKTypeKontent(valType, cache)
|
val updatedCache = generateKontent(valType, cache)
|
||||||
return updatedCache.plus(referenceName to schema)
|
return updatedCache.plus(referenceName to schema)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -240,9 +264,17 @@ object Kontent {
|
|||||||
val collectionClass = collectionType.classifier as KClass<*>
|
val collectionClass = collectionType.classifier as KClass<*>
|
||||||
logger.debug("Obtained collection class: $collectionClass")
|
logger.debug("Obtained collection class: $collectionClass")
|
||||||
val referenceName = genericNameAdapter(type, clazz)
|
val referenceName = genericNameAdapter(type, clazz)
|
||||||
val valueReference = ReferencedSchema("${COMPONENT_SLUG}/${collectionClass.simpleName}")
|
val valueReference = when (collectionClass.isSealed) {
|
||||||
|
true -> {
|
||||||
|
val subTypes = gatherSubTypes(collectionType)
|
||||||
|
AnyOfReferencedSchema(subTypes.map {
|
||||||
|
ReferencedSchema(("$COMPONENT_SLUG/${it.getSimpleSlug()}"))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
false -> ReferencedSchema("${COMPONENT_SLUG}/${collectionClass.simpleName}")
|
||||||
|
}
|
||||||
val schema = ArraySchema(items = valueReference)
|
val schema = ArraySchema(items = valueReference)
|
||||||
val updatedCache = generateKTypeKontent(collectionType, cache)
|
val updatedCache = generateKontent(collectionType, cache)
|
||||||
return updatedCache.plus(referenceName to schema)
|
return updatedCache.plus(referenceName to schema)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,9 @@ import io.bkbn.kompendium.util.notarizedGetWithNotarizedException
|
|||||||
import io.bkbn.kompendium.util.notarizedPostModule
|
import io.bkbn.kompendium.util.notarizedPostModule
|
||||||
import io.bkbn.kompendium.util.notarizedPutModule
|
import io.bkbn.kompendium.util.notarizedPutModule
|
||||||
import io.bkbn.kompendium.util.pathParsingTestModule
|
import io.bkbn.kompendium.util.pathParsingTestModule
|
||||||
|
import io.bkbn.kompendium.util.polymorphicCollectionResponse
|
||||||
|
import io.bkbn.kompendium.util.polymorphicInterfaceResponse
|
||||||
|
import io.bkbn.kompendium.util.polymorphicMapResponse
|
||||||
import io.bkbn.kompendium.util.polymorphicResponse
|
import io.bkbn.kompendium.util.polymorphicResponse
|
||||||
import io.bkbn.kompendium.util.primitives
|
import io.bkbn.kompendium.util.primitives
|
||||||
import io.bkbn.kompendium.util.returnsList
|
import io.bkbn.kompendium.util.returnsList
|
||||||
@ -457,6 +460,54 @@ internal class KompendiumTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `Can generate a collection with polymorphic response type`() {
|
||||||
|
withTestApplication({
|
||||||
|
jacksonConfigModule()
|
||||||
|
docs()
|
||||||
|
polymorphicCollectionResponse()
|
||||||
|
}) {
|
||||||
|
// do
|
||||||
|
val json = handleRequest(HttpMethod.Get, "/openapi.json").response.content
|
||||||
|
|
||||||
|
// expect
|
||||||
|
val expected = getFileSnapshot("polymorphic_list_response.json").trim()
|
||||||
|
assertEquals(expected, json, "The received json spec should match the expected content")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `Can generate a map with a polymorphic response type`() {
|
||||||
|
withTestApplication({
|
||||||
|
jacksonConfigModule()
|
||||||
|
docs()
|
||||||
|
polymorphicMapResponse()
|
||||||
|
}) {
|
||||||
|
// do
|
||||||
|
val json = handleRequest(HttpMethod.Get, "/openapi.json").response.content
|
||||||
|
|
||||||
|
// expect
|
||||||
|
val expected = getFileSnapshot("polymorphic_map_response.json").trim()
|
||||||
|
assertEquals(expected, json, "The received json spec should match the expected content")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `Can generate a polymorphic response from a sealed interface`() {
|
||||||
|
withTestApplication({
|
||||||
|
jacksonConfigModule()
|
||||||
|
docs()
|
||||||
|
polymorphicInterfaceResponse()
|
||||||
|
}) {
|
||||||
|
// do
|
||||||
|
val json = handleRequest(HttpMethod.Get, "/openapi.json").response.content
|
||||||
|
|
||||||
|
// expect
|
||||||
|
val expected = getFileSnapshot("sealed_interface_response.json").trim()
|
||||||
|
assertEquals(expected, json, "The received json spec should match the expected content")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `Can generate a response type with a generic type`() {
|
fun `Can generate a response type with a generic type`() {
|
||||||
withTestApplication({
|
withTestApplication({
|
||||||
|
@ -84,6 +84,12 @@ sealed class FlibbityGibbit
|
|||||||
data class SimpleGibbit(val a: String) : FlibbityGibbit()
|
data class SimpleGibbit(val a: String) : FlibbityGibbit()
|
||||||
data class ComplexGibbit(val b: String, val c: Int) : FlibbityGibbit()
|
data class ComplexGibbit(val b: String, val c: Int) : FlibbityGibbit()
|
||||||
|
|
||||||
|
sealed interface SlammaJamma
|
||||||
|
|
||||||
|
data class OneJamma(val a: Int) : SlammaJamma
|
||||||
|
data class AnothaJamma(val b: Float) : SlammaJamma
|
||||||
|
//data class InsaneJamma(val c: SlammaJamma) : SlammaJamma // 👀
|
||||||
|
|
||||||
sealed interface Flibbity<T>
|
sealed interface Flibbity<T>
|
||||||
|
|
||||||
data class Gibbity<T>(val a: T): Flibbity<T>
|
data class Gibbity<T>(val a: T): Flibbity<T>
|
||||||
|
@ -285,6 +285,36 @@ fun Application.polymorphicResponse() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun Application.polymorphicCollectionResponse() {
|
||||||
|
routing {
|
||||||
|
route("/test/polymorphiclist") {
|
||||||
|
notarizedGet(TestResponseInfo.polymorphicListResponse) {
|
||||||
|
call.respond(HttpStatusCode.OK, listOf(SimpleGibbit("hi")))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Application.polymorphicMapResponse() {
|
||||||
|
routing {
|
||||||
|
route("/test/polymorphicmap") {
|
||||||
|
notarizedGet(TestResponseInfo.polymorphicMapResponse) {
|
||||||
|
call.respond(HttpStatusCode.OK, listOf(SimpleGibbit("hi")))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Application.polymorphicInterfaceResponse() {
|
||||||
|
routing {
|
||||||
|
route("/test/polymorphicmap") {
|
||||||
|
notarizedGet(TestResponseInfo.polymorphicInterfaceResponse) {
|
||||||
|
call.respond(HttpStatusCode.OK, listOf(SimpleGibbit("hi")))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun Application.genericPolymorphicResponse() {
|
fun Application.genericPolymorphicResponse() {
|
||||||
routing {
|
routing {
|
||||||
route("/test/polymorphic") {
|
route("/test/polymorphic") {
|
||||||
|
@ -78,6 +78,21 @@ object TestResponseInfo {
|
|||||||
description = "Polymorphic response",
|
description = "Polymorphic response",
|
||||||
responseInfo = simpleOkResponse()
|
responseInfo = simpleOkResponse()
|
||||||
)
|
)
|
||||||
|
val polymorphicListResponse = GetInfo<Unit, List<FlibbityGibbit>>(
|
||||||
|
summary = "Oh so many gibbits",
|
||||||
|
description = "Polymorphic list response",
|
||||||
|
responseInfo = simpleOkResponse()
|
||||||
|
)
|
||||||
|
val polymorphicMapResponse = GetInfo<Unit, Map<String, FlibbityGibbit>>(
|
||||||
|
summary = "By gawd that's a lot of gibbits",
|
||||||
|
description = "Polymorphic list response",
|
||||||
|
responseInfo = simpleOkResponse()
|
||||||
|
)
|
||||||
|
val polymorphicInterfaceResponse = GetInfo<Unit, SlammaJamma>(
|
||||||
|
summary = "Come on and slam",
|
||||||
|
description = "and welcome to the jam",
|
||||||
|
responseInfo = simpleOkResponse()
|
||||||
|
)
|
||||||
val genericPolymorphicResponse = GetInfo<Unit, Flibbity<TestNested>>(
|
val genericPolymorphicResponse = GetInfo<Unit, Flibbity<TestNested>>(
|
||||||
summary = "More flibbity",
|
summary = "More flibbity",
|
||||||
description = "Polymorphic with generics",
|
description = "Polymorphic with generics",
|
||||||
|
@ -0,0 +1,91 @@
|
|||||||
|
{
|
||||||
|
"openapi" : "3.0.3",
|
||||||
|
"info" : {
|
||||||
|
"title" : "Test API",
|
||||||
|
"version" : "1.33.7",
|
||||||
|
"description" : "An amazing, fully-ish 😉 generated API spec",
|
||||||
|
"termsOfService" : "https://example.com",
|
||||||
|
"contact" : {
|
||||||
|
"name" : "Homer Simpson",
|
||||||
|
"url" : "https://gph.is/1NPUDiM",
|
||||||
|
"email" : "chunkylover53@aol.com"
|
||||||
|
},
|
||||||
|
"license" : {
|
||||||
|
"name" : "MIT",
|
||||||
|
"url" : "https://github.com/bkbnio/kompendium/blob/main/LICENSE"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"servers" : [ {
|
||||||
|
"url" : "https://myawesomeapi.com",
|
||||||
|
"description" : "Production instance of my API"
|
||||||
|
}, {
|
||||||
|
"url" : "https://staging.myawesomeapi.com",
|
||||||
|
"description" : "Where the fun stuff happens"
|
||||||
|
} ],
|
||||||
|
"paths" : {
|
||||||
|
"/test/polymorphiclist" : {
|
||||||
|
"get" : {
|
||||||
|
"tags" : [ ],
|
||||||
|
"summary" : "Oh so many gibbits",
|
||||||
|
"description" : "Polymorphic list response",
|
||||||
|
"parameters" : [ ],
|
||||||
|
"responses" : {
|
||||||
|
"200" : {
|
||||||
|
"description" : "A successful endeavor",
|
||||||
|
"content" : {
|
||||||
|
"application/json" : {
|
||||||
|
"schema" : {
|
||||||
|
"$ref" : "#/components/schemas/List-FlibbityGibbit"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"deprecated" : false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"components" : {
|
||||||
|
"schemas" : {
|
||||||
|
"String" : {
|
||||||
|
"type" : "string"
|
||||||
|
},
|
||||||
|
"SimpleGibbit" : {
|
||||||
|
"type" : "object",
|
||||||
|
"properties" : {
|
||||||
|
"a" : {
|
||||||
|
"$ref" : "#/components/schemas/String"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Int" : {
|
||||||
|
"type" : "integer",
|
||||||
|
"format" : "int32"
|
||||||
|
},
|
||||||
|
"ComplexGibbit" : {
|
||||||
|
"type" : "object",
|
||||||
|
"properties" : {
|
||||||
|
"b" : {
|
||||||
|
"$ref" : "#/components/schemas/String"
|
||||||
|
},
|
||||||
|
"c" : {
|
||||||
|
"$ref" : "#/components/schemas/Int"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"List-FlibbityGibbit" : {
|
||||||
|
"type" : "array",
|
||||||
|
"items" : {
|
||||||
|
"anyOf" : [ {
|
||||||
|
"$ref" : "#/components/schemas/SimpleGibbit"
|
||||||
|
}, {
|
||||||
|
"$ref" : "#/components/schemas/ComplexGibbit"
|
||||||
|
} ]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"securitySchemes" : { }
|
||||||
|
},
|
||||||
|
"security" : [ ],
|
||||||
|
"tags" : [ ]
|
||||||
|
}
|
@ -0,0 +1,91 @@
|
|||||||
|
{
|
||||||
|
"openapi" : "3.0.3",
|
||||||
|
"info" : {
|
||||||
|
"title" : "Test API",
|
||||||
|
"version" : "1.33.7",
|
||||||
|
"description" : "An amazing, fully-ish 😉 generated API spec",
|
||||||
|
"termsOfService" : "https://example.com",
|
||||||
|
"contact" : {
|
||||||
|
"name" : "Homer Simpson",
|
||||||
|
"url" : "https://gph.is/1NPUDiM",
|
||||||
|
"email" : "chunkylover53@aol.com"
|
||||||
|
},
|
||||||
|
"license" : {
|
||||||
|
"name" : "MIT",
|
||||||
|
"url" : "https://github.com/bkbnio/kompendium/blob/main/LICENSE"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"servers" : [ {
|
||||||
|
"url" : "https://myawesomeapi.com",
|
||||||
|
"description" : "Production instance of my API"
|
||||||
|
}, {
|
||||||
|
"url" : "https://staging.myawesomeapi.com",
|
||||||
|
"description" : "Where the fun stuff happens"
|
||||||
|
} ],
|
||||||
|
"paths" : {
|
||||||
|
"/test/polymorphicmap" : {
|
||||||
|
"get" : {
|
||||||
|
"tags" : [ ],
|
||||||
|
"summary" : "By gawd that's a lot of gibbits",
|
||||||
|
"description" : "Polymorphic list response",
|
||||||
|
"parameters" : [ ],
|
||||||
|
"responses" : {
|
||||||
|
"200" : {
|
||||||
|
"description" : "A successful endeavor",
|
||||||
|
"content" : {
|
||||||
|
"application/json" : {
|
||||||
|
"schema" : {
|
||||||
|
"$ref" : "#/components/schemas/Map-String-FlibbityGibbit"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"deprecated" : false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"components" : {
|
||||||
|
"schemas" : {
|
||||||
|
"String" : {
|
||||||
|
"type" : "string"
|
||||||
|
},
|
||||||
|
"SimpleGibbit" : {
|
||||||
|
"type" : "object",
|
||||||
|
"properties" : {
|
||||||
|
"a" : {
|
||||||
|
"$ref" : "#/components/schemas/String"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Int" : {
|
||||||
|
"type" : "integer",
|
||||||
|
"format" : "int32"
|
||||||
|
},
|
||||||
|
"ComplexGibbit" : {
|
||||||
|
"type" : "object",
|
||||||
|
"properties" : {
|
||||||
|
"b" : {
|
||||||
|
"$ref" : "#/components/schemas/String"
|
||||||
|
},
|
||||||
|
"c" : {
|
||||||
|
"$ref" : "#/components/schemas/Int"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Map-String-FlibbityGibbit" : {
|
||||||
|
"type" : "object",
|
||||||
|
"additionalProperties" : {
|
||||||
|
"anyOf" : [ {
|
||||||
|
"$ref" : "#/components/schemas/SimpleGibbit"
|
||||||
|
}, {
|
||||||
|
"$ref" : "#/components/schemas/ComplexGibbit"
|
||||||
|
} ]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"securitySchemes" : { }
|
||||||
|
},
|
||||||
|
"security" : [ ],
|
||||||
|
"tags" : [ ]
|
||||||
|
}
|
@ -0,0 +1,83 @@
|
|||||||
|
{
|
||||||
|
"openapi" : "3.0.3",
|
||||||
|
"info" : {
|
||||||
|
"title" : "Test API",
|
||||||
|
"version" : "1.33.7",
|
||||||
|
"description" : "An amazing, fully-ish 😉 generated API spec",
|
||||||
|
"termsOfService" : "https://example.com",
|
||||||
|
"contact" : {
|
||||||
|
"name" : "Homer Simpson",
|
||||||
|
"url" : "https://gph.is/1NPUDiM",
|
||||||
|
"email" : "chunkylover53@aol.com"
|
||||||
|
},
|
||||||
|
"license" : {
|
||||||
|
"name" : "MIT",
|
||||||
|
"url" : "https://github.com/bkbnio/kompendium/blob/main/LICENSE"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"servers" : [ {
|
||||||
|
"url" : "https://myawesomeapi.com",
|
||||||
|
"description" : "Production instance of my API"
|
||||||
|
}, {
|
||||||
|
"url" : "https://staging.myawesomeapi.com",
|
||||||
|
"description" : "Where the fun stuff happens"
|
||||||
|
} ],
|
||||||
|
"paths" : {
|
||||||
|
"/test/polymorphicmap" : {
|
||||||
|
"get" : {
|
||||||
|
"tags" : [ ],
|
||||||
|
"summary" : "Come on and slam",
|
||||||
|
"description" : "and welcome to the jam",
|
||||||
|
"parameters" : [ ],
|
||||||
|
"responses" : {
|
||||||
|
"200" : {
|
||||||
|
"description" : "A successful endeavor",
|
||||||
|
"content" : {
|
||||||
|
"application/json" : {
|
||||||
|
"schema" : {
|
||||||
|
"anyOf" : [ {
|
||||||
|
"$ref" : "#/components/schemas/OneJamma"
|
||||||
|
}, {
|
||||||
|
"$ref" : "#/components/schemas/AnothaJamma"
|
||||||
|
} ]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"deprecated" : false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"components" : {
|
||||||
|
"schemas" : {
|
||||||
|
"Int" : {
|
||||||
|
"type" : "integer",
|
||||||
|
"format" : "int32"
|
||||||
|
},
|
||||||
|
"OneJamma" : {
|
||||||
|
"type" : "object",
|
||||||
|
"properties" : {
|
||||||
|
"a" : {
|
||||||
|
"$ref" : "#/components/schemas/Int"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Float" : {
|
||||||
|
"type" : "number",
|
||||||
|
"format" : "float"
|
||||||
|
},
|
||||||
|
"AnothaJamma" : {
|
||||||
|
"type" : "object",
|
||||||
|
"properties" : {
|
||||||
|
"b" : {
|
||||||
|
"$ref" : "#/components/schemas/Float"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"securitySchemes" : { }
|
||||||
|
},
|
||||||
|
"security" : [ ],
|
||||||
|
"tags" : [ ]
|
||||||
|
}
|
Reference in New Issue
Block a user