allow custom type overrides (#83)

This commit is contained in:
Ryan Brink
2021-08-12 21:38:48 -04:00
committed by GitHub
parent 3d99bf35fd
commit b021935b10
7 changed files with 56 additions and 1 deletions

View File

@ -1,5 +1,11 @@
# Changelog # Changelog
## [1.6.0] - August 12, 2021
### Added
- Ability to add custom type schema overrides for edge case types.
## [1.5.1] - August 12th, 2021 ## [1.5.1] - August 12th, 2021
### Changed ### Changed

View File

@ -216,6 +216,25 @@ routing {
} }
``` ```
## Custom Type Overrides
Kompendium does its best to analyze types and to generate an OpenAPI format accordingly. However, there are certain
classes that just don't play nice with the standard reflection analysis that Kompendium performs.
Should you encounter a data type that Kompendium cannot comprehend, you will need to
add it explicitly. For example, adding the Joda Time `DateTime` object would be as simple as the following
```kotlin
Kompendium.addCustomTypeSchema(DateTime::class, FormatSchema("date-time", "string"))
```
Since `Kompendium` is an object, this needs to be declared once, ahead of the actual API instantiation. This way, this
type override can be cached ahead of reflection. Kompendium will then match all instances of this type and return the
specified schema.
So how do you know a type can and cannot be inferred? The safe bet is that it can be. So go ahead and give it a shot.
However, in the very odd scenario (almost always having to do with date/time libraries 😤) where it can't, you can rest
safely knowing that you have the option to inject a custom override should you need to.
## Limitations ## Limitations
### Kompendium as a singleton ### Kompendium as a singleton
@ -234,7 +253,6 @@ should have. There are several outstanding features that have been added to the
- AsyncAPI Integration - AsyncAPI Integration
- Field Validation - Field Validation
- MavenCentral Release
If you have a feature that you would like to see implemented that is not on this list, or discover a 🐞, please open If you have a feature that you would like to see implemented that is not on this list, or discover a 🐞, please open
an issue [here](https://github.com/bkbnio/kompendium/issues/new) an issue [here](https://github.com/bkbnio/kompendium/issues/new)

View File

@ -4,8 +4,10 @@ import io.bkbn.kompendium.models.meta.ErrorMap
import io.bkbn.kompendium.models.meta.SchemaMap import io.bkbn.kompendium.models.meta.SchemaMap
import io.bkbn.kompendium.models.oas.OpenApiSpec import io.bkbn.kompendium.models.oas.OpenApiSpec
import io.bkbn.kompendium.models.oas.OpenApiSpecInfo import io.bkbn.kompendium.models.oas.OpenApiSpecInfo
import io.bkbn.kompendium.models.oas.TypedSchema
import io.bkbn.kompendium.path.CorePathCalculator import io.bkbn.kompendium.path.CorePathCalculator
import io.bkbn.kompendium.path.PathCalculator import io.bkbn.kompendium.path.PathCalculator
import kotlin.reflect.KClass
/** /**
* Maintains all state for the Kompendium library * Maintains all state for the Kompendium library
@ -31,4 +33,8 @@ object Kompendium {
) )
cache = emptyMap() cache = emptyMap()
} }
fun addCustomTypeSchema(clazz: KClass<*>, schema: TypedSchema) {
cache = cache.plus(clazz.simpleName!! to schema)
}
} }

View File

@ -18,6 +18,8 @@ dependencies {
implementation(libs.bundles.ktorAuth) implementation(libs.bundles.ktorAuth)
implementation(libs.bundles.logging) implementation(libs.bundles.logging)
implementation("joda-time:joda-time:2.10.10")
testImplementation("org.jetbrains.kotlin:kotlin-test") testImplementation("org.jetbrains.kotlin:kotlin-test")
testImplementation("org.jetbrains.kotlin:kotlin-test-junit") testImplementation("org.jetbrains.kotlin:kotlin-test-junit")
} }

View File

@ -1,5 +1,6 @@
package io.bkbn.kompendium.playground package io.bkbn.kompendium.playground
import io.bkbn.kompendium.Kompendium
import io.bkbn.kompendium.Notarized.notarizedDelete import io.bkbn.kompendium.Notarized.notarizedDelete
import io.bkbn.kompendium.Notarized.notarizedException import io.bkbn.kompendium.Notarized.notarizedException
import io.bkbn.kompendium.Notarized.notarizedGet import io.bkbn.kompendium.Notarized.notarizedGet
@ -7,7 +8,9 @@ import io.bkbn.kompendium.Notarized.notarizedPost
import io.bkbn.kompendium.Notarized.notarizedPut import io.bkbn.kompendium.Notarized.notarizedPut
import io.bkbn.kompendium.auth.KompendiumAuth.notarizedBasic import io.bkbn.kompendium.auth.KompendiumAuth.notarizedBasic
import io.bkbn.kompendium.models.meta.ResponseInfo import io.bkbn.kompendium.models.meta.ResponseInfo
import io.bkbn.kompendium.models.oas.FormatSchema
import io.bkbn.kompendium.playground.PlaygroundToC.testAuthenticatedSingleGetInfo import io.bkbn.kompendium.playground.PlaygroundToC.testAuthenticatedSingleGetInfo
import io.bkbn.kompendium.playground.PlaygroundToC.testCustomOverride
import io.bkbn.kompendium.playground.PlaygroundToC.testGetWithExamples import io.bkbn.kompendium.playground.PlaygroundToC.testGetWithExamples
import io.bkbn.kompendium.playground.PlaygroundToC.testIdGetInfo import io.bkbn.kompendium.playground.PlaygroundToC.testIdGetInfo
import io.bkbn.kompendium.playground.PlaygroundToC.testPostWithExamples import io.bkbn.kompendium.playground.PlaygroundToC.testPostWithExamples
@ -36,8 +39,11 @@ import io.ktor.serialization.json
import io.ktor.server.engine.embeddedServer import io.ktor.server.engine.embeddedServer
import io.ktor.server.netty.Netty import io.ktor.server.netty.Netty
import io.ktor.webjars.Webjars import io.ktor.webjars.Webjars
import org.joda.time.DateTime
fun main() { fun main() {
Kompendium.addCustomTypeSchema(DateTime::class, FormatSchema("date-time", "string"))
embeddedServer( embeddedServer(
Netty, Netty,
port = 8081, port = 8081,
@ -114,6 +120,11 @@ fun Application.mainModule() {
call.respondText { "heya" } call.respondText { "heya" }
} }
} }
route("custom_override") {
notarizedGet(testCustomOverride) {
call.respondText { DateTime.now().toString() }
}
}
authenticate("basic") { authenticate("basic") {
route("/authenticated/single") { route("/authenticated/single") {
notarizedGet(testAuthenticatedSingleGetInfo) { notarizedGet(testAuthenticatedSingleGetInfo) {

View File

@ -3,6 +3,7 @@ package io.bkbn.kompendium.playground
import io.bkbn.kompendium.annotations.KompendiumField import io.bkbn.kompendium.annotations.KompendiumField
import io.bkbn.kompendium.annotations.KompendiumParam import io.bkbn.kompendium.annotations.KompendiumParam
import io.bkbn.kompendium.annotations.ParamType import io.bkbn.kompendium.annotations.ParamType
import org.joda.time.DateTime
data class ExampleParams( data class ExampleParams(
@KompendiumParam(ParamType.PATH) val id: Int, @KompendiumParam(ParamType.PATH) val id: Int,
@ -30,3 +31,5 @@ data class ExampleResponse(val c: String)
data class ExceptionResponse(val message: String) data class ExceptionResponse(val message: String)
data class ExampleCreatedResponse(val id: Int, val c: String) data class ExampleCreatedResponse(val id: Int, val c: String)
data class DateTimeWrapper(val dt: DateTime)

View File

@ -55,6 +55,15 @@ object PlaygroundToC {
description = "Returns a different sample" description = "Returns a different sample"
) )
) )
val testCustomOverride = MethodInfo.GetInfo<Unit, DateTimeWrapper>(
summary = "custom schema test",
description = "testing",
tags = setOf("custom"),
responseInfo = ResponseInfo(
status = HttpStatusCode.OK,
description = "good tings"
)
)
val testSingleGetInfoWithThrowable = testSingleGetInfo.copy( val testSingleGetInfoWithThrowable = testSingleGetInfo.copy(
summary = "Show me the error baby 🙏", summary = "Show me the error baby 🙏",
canThrow = setOf(Exception::class) canThrow = setOf(Exception::class)