Skip to content

Commit

Permalink
Merge branch 'develop' into release
Browse files Browse the repository at this point in the history
  • Loading branch information
SMILEY4 committed Apr 17, 2023
2 parents 83d5186 + b5da05f commit 972224e
Show file tree
Hide file tree
Showing 6 changed files with 180 additions and 3 deletions.
6 changes: 3 additions & 3 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@ plugins {
}

group = "io.github.smiley4"
version = "1.5.0"
version = "1.6.0"

repositories {
mavenCentral()
}

dependencies {

val ktorVersion = "2.2.3"
val ktorVersion = "2.2.4"
implementation("io.ktor:ktor-server-core-jvm:$ktorVersion")
implementation("io.ktor:ktor-server-webjars:$ktorVersion")
implementation("io.ktor:ktor-server-auth:$ktorVersion")
Expand All @@ -39,7 +39,7 @@ dependencies {
val kotlinLoggingVersion = "2.1.23"
implementation("io.github.microutils:kotlin-logging-jvm:$kotlinLoggingVersion")

val logbackVersion = "1.2.11"
val logbackVersion = "1.4.5"
testImplementation("ch.qos.logback:logback-classic:$logbackVersion")

val versionMockk = "1.12.7"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
package io.github.smiley4.ktorswaggerui

import com.fasterxml.jackson.databind.node.ObjectNode
import com.github.victools.jsonschema.generator.FieldScope
import com.github.victools.jsonschema.generator.Option
import com.github.victools.jsonschema.generator.OptionPreset
import com.github.victools.jsonschema.generator.SchemaGenerationContext
import com.github.victools.jsonschema.generator.SchemaGeneratorConfigBuilder
import com.github.victools.jsonschema.generator.SchemaVersion
import com.github.victools.jsonschema.generator.TypeScope
import com.github.victools.jsonschema.module.jackson.JacksonModule
import com.github.victools.jsonschema.module.swagger2.Swagger2Module
import io.github.smiley4.ktorswaggerui.dsl.CustomSchemas
import io.github.smiley4.ktorswaggerui.dsl.Example
import io.github.smiley4.ktorswaggerui.dsl.OpenApiDslMarker
import io.github.smiley4.ktorswaggerui.dsl.OpenApiInfo
import io.github.smiley4.ktorswaggerui.dsl.OpenApiResponse
Expand All @@ -17,6 +22,7 @@ import io.github.smiley4.ktorswaggerui.dsl.SwaggerUI
import io.ktor.http.HttpMethod
import io.ktor.http.HttpStatusCode
import io.ktor.server.routing.RouteSelector
import io.swagger.v3.oas.annotations.media.Schema
import kotlin.reflect.KClass

/**
Expand Down Expand Up @@ -163,6 +169,21 @@ class SwaggerUIPluginConfig {
.with(Option.EXTRA_OPEN_API_FORMAT_VALUES)
.with(Option.ALLOF_CLEANUP_AT_THE_END)
.with(Option.MAP_VALUES_AS_ADDITIONAL_PROPERTIES)
.also {
it.forTypesInGeneral()
.withTypeAttributeOverride { objectNode: ObjectNode, typeScope: TypeScope, _: SchemaGenerationContext ->
if (typeScope is FieldScope) {
typeScope.getAnnotation(Schema::class.java)?.also { annotation ->
if (annotation.example != "") {
objectNode.put("example", annotation.example)
}
}
typeScope.getAnnotation(Example::class.java)?.also { annotation ->
objectNode.put("example", annotation.value)
}
}
}
}


/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package io.github.smiley4.ktorswaggerui.dsl

/**
* Annotation to add an example value to the field of an object.
*/
@Target(AnnotationTarget.FIELD)
annotation class Example(
val value: String
)
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import com.fasterxml.jackson.databind.JsonNode
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.databind.node.ArrayNode
import io.swagger.v3.oas.models.media.Schema
import java.math.BigDecimal

class JsonToOpenApiSchemaConverter {

Expand All @@ -14,13 +15,22 @@ class JsonToOpenApiSchemaConverter {
node["\$schema"]?.let { this.`$schema` = it.asText() }
node["description"]?.let { this.description = it.asText() }
node["title"]?.let { this.title = it.asText() }
node["example"]?.let { this.example(it.asText()) }
node["type"]?.let {
val types = if (it is ArrayNode) it.collectElements().map { e -> e.asText() } else listOf(it.asText())
this.type = types.firstOrNull { e -> e != "null" }
if (types.contains("null")) {
this.nullable = true
}
}
node["deprecated"]?.let { this.deprecated = it.asBoolean() }
node["minLength"]?.let { this.minLength = it.asInt() }
node["maxLength"]?.let { this.maxLength = it.asInt() }
node["minimum"]?.let { this.minimum = BigDecimal(it.asText()) }
node["maximum"]?.let { this.maximum = BigDecimal(it.asText()) }
node["maxItems"]?.let { this.maxItems = it.asInt() }
node["minItems"]?.let { this.minItems = it.asInt() }
node["uniqueItems"]?.let { this.uniqueItems = it.asBoolean() }
node["format"]?.let { this.format = it.asText() }
node["items"]?.let { this.items = toSchema(it) }
node["properties"]?.let { this.properties = it.collectFields().associate { prop -> prop.key to toSchema(prop.value) } }
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
package io.github.smiley4.ktorswaggerui.examples

import io.github.smiley4.ktorswaggerui.SwaggerUI
import io.github.smiley4.ktorswaggerui.dsl.Example
import io.github.smiley4.ktorswaggerui.dsl.get
import io.ktor.http.HttpStatusCode
import io.ktor.server.application.Application
import io.ktor.server.application.call
import io.ktor.server.application.install
import io.ktor.server.engine.embeddedServer
import io.ktor.server.netty.Netty
import io.ktor.server.response.respondText
import io.ktor.server.routing.routing
import io.swagger.v3.oas.annotations.media.ArraySchema
import io.swagger.v3.oas.annotations.media.Schema

/**
* An example showcasing examples with the [Schema] and [io.github.smiley4.ktorswaggerui.dsl.Example]-Annotation
*/
fun main() {
embeddedServer(Netty, port = 8080, host = "localhost", module = Application::myModule).start(wait = true)
}

private fun Application.myModule() {
install(SwaggerUI)
routing {
get("person/example", {
request {
body<ExamplePerson>()
}
response {
HttpStatusCode.OK to {
body<ExamplePerson>()
}
}
}) {
call.respondText("...")
}
get("person/schema", {
request {
body<SchemaPerson>()
}
response {
HttpStatusCode.OK to {
body<SchemaPerson>()
}
}
}) {
call.respondText("...")
}
}
}

data class ExamplePerson(

@Example("red")
val favColor: String,

@Example("Steve")
val name: String,

@Example("42")
val age: Int,

@Example("172")
val size: Float,

@Example("false")
val robot: Boolean,

val address: ExampleAddress,

val secondaryAddresses: List<ExampleAddress>
)

data class ExampleAddress(

@Example("New City")
val city: String,

@Example("12345")
val code: Int

)

@Schema(description = "Schema of some person", title = "Person")
data class SchemaPerson(

@field:Schema(example = "red")
val favColor: String,

@field:Schema(example = "Steve", minLength = 1, maxLength = 32)
val name: String,

@field:Schema(example = "42", minimum = "18", maximum = "99")
val age: Int,

@field:Schema(example = "172", format = "int32")
val size: Float,

@field:Schema(example = "false")
val robot: Boolean,

val address: SchemaAddress,

@field:ArraySchema(minItems = 1, maxItems = 32, uniqueItems = true)
val secondaryAddresses: List<SchemaAddress>
)

@Schema(description = "Schema of some address", title = "Address")
data class SchemaAddress(

@field:Schema(example = "New City")
val city: String,

@field:Schema(example = "12345")
val code: Int

)
18 changes: 18 additions & 0 deletions src/test/resources/logback.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<configuration>

<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>
%cyan(%d{yyyy-MM-dd HH:mm:ss.SSS}) | %highlight(%-5.5level{5}) | %gray(%-16.16thread{16}) | %magenta(%-25.25logger{25}) | %m%n
</pattern>
</encoder>
</appender>

<root level="debug">
<appender-ref ref="STDOUT"/>
</root>

<logger name="io.netty" level="INFO"/>
<logger name="com.arangodb" level="INFO"/>

</configuration>

0 comments on commit 972224e

Please sign in to comment.