diff --git a/CHANGELOG.md b/CHANGELOG.md index 295708f99..69ea5d186 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## [1.11.1] - November 25th, 2021 +### Added +- Documentation showing how to add header names using Kotlin backtick convention + ## [1.11.0] - November 25th, 2021 ### Added - Support for Ktor Location Plugin diff --git a/README.md b/README.md index f80f75669..f08918f7c 100644 --- a/README.md +++ b/README.md @@ -109,6 +109,14 @@ of camel). The purpose of `KompendiumParam` is to provide supplemental information needed to properly assign the type of parameter (cookie, header, query, path) as well as other parameter-level metadata. +Using backticks, users can use data classes to represent things like header names as follows + +```kotlin +data class HeaderNameTest( + @KompendiumParam(type = ParamType.HEADER) val `X-UserEmail`: String +) +``` + ### Undeclared Field There is also a final `UndeclaredField` annotation. This should be used only in an absolutely emergency. This annotation diff --git a/gradle.properties b/gradle.properties index f0c21eafe..383684c82 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ # Kompendium -project.version=1.11.0 +project.version=1.11.1 # Kotlin kotlin.code.style=official # Gradle diff --git a/kompendium-core/src/main/kotlin/io/bkbn/kompendium/annotations/KompendiumParam.kt b/kompendium-core/src/main/kotlin/io/bkbn/kompendium/annotations/KompendiumParam.kt index a8fc10517..7752563f0 100644 --- a/kompendium-core/src/main/kotlin/io/bkbn/kompendium/annotations/KompendiumParam.kt +++ b/kompendium-core/src/main/kotlin/io/bkbn/kompendium/annotations/KompendiumParam.kt @@ -1,5 +1,10 @@ package io.bkbn.kompendium.annotations +/** + * Used to indicate that a field in a data class represents an OpenAPI parameter + * @param type The type of parameter, must be valid [ParamType] + * @param description Description of the parameter to include in OpenAPI Spec + */ @Retention(AnnotationRetention.RUNTIME) @Target(AnnotationTarget.PROPERTY) annotation class KompendiumParam(val type: ParamType, val description: String = "") diff --git a/kompendium-core/src/test/kotlin/io/bkbn/kompendium/KompendiumTest.kt b/kompendium-core/src/test/kotlin/io/bkbn/kompendium/KompendiumTest.kt index 15aea7b87..03bc09d76 100644 --- a/kompendium-core/src/test/kotlin/io/bkbn/kompendium/KompendiumTest.kt +++ b/kompendium-core/src/test/kotlin/io/bkbn/kompendium/KompendiumTest.kt @@ -22,6 +22,7 @@ import io.bkbn.kompendium.util.jacksonConfigModule import io.bkbn.kompendium.util.emptyGet import io.bkbn.kompendium.util.genericPolymorphicResponse import io.bkbn.kompendium.util.genericPolymorphicResponseMultipleImpls +import io.bkbn.kompendium.util.headerParameter import io.bkbn.kompendium.util.kotlinxConfigModule import io.bkbn.kompendium.util.nestedUnderRootModule import io.bkbn.kompendium.util.nonRequiredParamsGet @@ -589,6 +590,22 @@ internal class KompendiumTest { } } + @Test + fun `Can add a custom header parameter with a name override`() { + withTestApplication({ + jacksonConfigModule() + docs() + headerParameter() + }) { + // do + val json = handleRequest(HttpMethod.Get, "/openapi.json").response.content + + // expect + val expected = getFileSnapshot("override_parameter_name.json").trim() + assertEquals(expected, json, "The received json spec should match the expected content") + } + } + private val oas = Kompendium.openApiSpec.copy( info = OpenApiSpecInfo( title = "Test API", diff --git a/kompendium-core/src/test/kotlin/io/bkbn/kompendium/util/TestModels.kt b/kompendium-core/src/test/kotlin/io/bkbn/kompendium/util/TestModels.kt index d7ee55224..0f738d072 100644 --- a/kompendium-core/src/test/kotlin/io/bkbn/kompendium/util/TestModels.kt +++ b/kompendium-core/src/test/kotlin/io/bkbn/kompendium/util/TestModels.kt @@ -105,3 +105,7 @@ enum class Hehe { @UndeclaredField("nowYouDont", Hehe::class) data class Mysterious(val nowYouSeeMe: String) + +data class HeaderNameTest( + @KompendiumParam(type = ParamType.HEADER) val `X-UserEmail`: String +) diff --git a/kompendium-core/src/test/kotlin/io/bkbn/kompendium/util/TestModules.kt b/kompendium-core/src/test/kotlin/io/bkbn/kompendium/util/TestModules.kt index f54b4c48f..913eaefc7 100644 --- a/kompendium-core/src/test/kotlin/io/bkbn/kompendium/util/TestModules.kt +++ b/kompendium-core/src/test/kotlin/io/bkbn/kompendium/util/TestModules.kt @@ -362,6 +362,16 @@ fun Application.undeclaredType() { } } +fun Application.headerParameter() { + routing { + route("/test/with_header") { + notarizedGet(TestResponseInfo.headerParam) { + call.respond(HttpStatusCode.OK, TestResponse("hi")) + } + } + } +} + fun Application.simpleGenericResponse() { routing { route("/test/polymorphic") { diff --git a/kompendium-core/src/test/kotlin/io/bkbn/kompendium/util/TestResponseInfo.kt b/kompendium-core/src/test/kotlin/io/bkbn/kompendium/util/TestResponseInfo.kt index 3e1f1a838..028d57844 100644 --- a/kompendium-core/src/test/kotlin/io/bkbn/kompendium/util/TestResponseInfo.kt +++ b/kompendium-core/src/test/kotlin/io/bkbn/kompendium/util/TestResponseInfo.kt @@ -108,6 +108,11 @@ object TestResponseInfo { description = "break this glass in scenario of emergency", responseInfo = simpleOkResponse() ) + val headerParam = GetInfo( + summary = "testing header stuffs", + description = "Good for many things", + responseInfo = simpleOkResponse() + ) val genericResponse = GetInfo>( summary = "Single Generic", description = "Simple generic data class", diff --git a/kompendium-core/src/test/resources/override_parameter_name.json b/kompendium-core/src/test/resources/override_parameter_name.json new file mode 100644 index 000000000..52f272588 --- /dev/null +++ b/kompendium-core/src/test/resources/override_parameter_name.json @@ -0,0 +1,74 @@ +{ + "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/with_header" : { + "get" : { + "tags" : [ ], + "summary" : "testing header stuffs", + "description" : "Good for many things", + "parameters" : [ { + "name" : "X-UserEmail", + "in" : "header", + "schema" : { + "type" : "string" + }, + "required" : true, + "deprecated" : false + } ], + "responses" : { + "200" : { + "description" : "A successful endeavor", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/TestResponse" + } + } + } + } + }, + "deprecated" : false + } + } + }, + "components" : { + "schemas" : { + "String" : { + "type" : "string" + }, + "TestResponse" : { + "type" : "object", + "properties" : { + "c" : { + "$ref" : "#/components/schemas/String" + } + } + } + }, + "securitySchemes" : { } + }, + "security" : [ ], + "tags" : [ ] +}