James Richardson
02/19/2021, 7:35 AMElizabeth Thomas
02/20/2021, 1:24 AMrequired
attribute as []
. I tried setting @JsonProperty(required = true)
on the field as well, but still no luck. Would you have other thoughts?dave
02/20/2021, 11:05 AMJames Richardson
02/20/2021, 1:04 PMElizabeth Thomas
02/23/2021, 3:45 PMdata class SumResult(val sum: Int)
val sumResponseBody = Body.auto<SumResult>().toLens()
fun main(args: Array<String>) {
fun add(value1: Int, value2: Int): HttpHandler = {
Response(OK).with(
sumResponseBody of SumResult(value1 + value2)
)
}
val filter: Filter = ResponseFilters.ReportHttpTransaction(Clock.systemUTC()) { tx: HttpTransaction ->
println(tx.labels.toString() + " took " + tx.duration)
}
val mySecurity = ApiKeySecurity(<http://Query.int|Query.int>().required("apiKey"), { it == 42 })
val contract = contract {
renderer = OpenApi3(ApiInfo("my great api", "v1.0"), OpenApiJackson, emptyList(), OpenApi3ApiRenderer(OpenApiJackson))
descriptionPath = "/docs/swagger.json"
security = mySecurity
routes += "/add" / <http://Path.int|Path.int>().of("value1") / <http://Path.int|Path.int>().of("value2") meta {
summary = "add"
description = "Adds 2 numbers together"
returning(OK, sumResponseBody to SumResult(55))
} bindContract Method.GET to ::add
}
val handler = routes(
"/context" bind filter.then(contract),
"/" bind contract {
renderer = OpenApi3(ApiInfo("my great super api", "v1.0"), OpenApiJackson, emptyList(), OpenApi3ApiRenderer(OpenApiJackson))
}
)
ServerFilters.Cors(CorsPolicy.UnsafeGlobalPermissive).then(handler).asServer(Jetty(8000)).start()
}
localhost:8080/context/docs/swagger.json
on my browser or curl command, the output I get is this
{
"openapi": "3.0.0",
"info": {
"title": "my great api",
"version": "v1.0",
"description": ""
},
"tags": [],
"paths": {
"/context/add/{value1}/{value2}": {
"get": {
"summary": "add",
"description": "Adds 2 numbers together",
"tags": [
"/context"
],
"parameters": [
{
"schema": {
"type": "integer"
},
"in": "path",
"name": "value1",
"required": true,
"description": null
},
{
"schema": {
"type": "integer"
},
"in": "path",
"name": "value2",
"required": true,
"description": null
}
],
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"example": {
"sum": 55
},
"schema": {
"$ref": "#/components/schemas/object-1725201476"
}
}
}
}
},
"security": [
{
"api_key": []
}
],
"operationId": "getContextAdd_value1__value2",
"deprecated": false
}
}
},
"components": {
"schemas": {
"object-1725201476": {
"type": "object",
"required": [],
"properties": {
"sum": {
"type": "integer",
"example": 55
}
}
}
},
"securitySchemes": {
"api_key": {
"type": "apiKey",
"in": "query",
"name": "apiKey"
}
}
}
}
components.schemas.object-1725201476
, required
comes back as []
even though my data class SumResult
has sum
property as not nullable.object ObjectMappers {
val snakeCaseMapper: ObjectMapper get() = createMapper()
fun createMapper(namingStrategy: PropertyNamingStrategy = PropertyNamingStrategy.SNAKE_CASE): ObjectMapper =
ObjectMapper()
.findAndRegisterModules()
.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)
.configure(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE, false)
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.configure(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL, true)
.configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY, true)
.configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS, true)
.setPropertyNamingStrategy(namingStrategy)
}
object OpenApiJackson : ConfigurableJackson(ObjectMappers.snakeCaseMapper)
required
field to be filled with non-nullable properties of my response object in my exampledave
02/23/2021, 4:03 PMobject Jackson : ConfigurableJackson(KotlinModule()
.asConfigurable()
.withStandardMappings()
.done()
.deactivateDefaultTyping()
.configure(FAIL_ON_UNKNOWN_PROPERTIES, false)
.configure(FAIL_ON_IGNORED_PROPERTIES, false)
.configure(USE_BIG_DECIMAL_FOR_FLOATS, true)
.configure(USE_BIG_INTEGER_FOR_INTS, true)
)
Elizabeth Thomas
02/23/2021, 4:05 PMrequired
comes back as []
in the component schema objectsdave
02/23/2021, 4:10 PMElizabeth Thomas
02/23/2021, 4:13 PMdave
02/23/2021, 4:34 PMElizabeth Thomas
02/23/2021, 4:39 PMobject Jackson : ConfigurableJackson(KotlinModule()
.asConfigurable()
.withStandardMappings()
.done()
.deactivateDefaultTyping()
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.configure(DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES, false)
.configure(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS, true)
.configure(DeserializationFeature.USE_BIG_INTEGER_FOR_INTS, true)
)
package com.test.openapi
import com.test.openapi.Jackson.auto
import org.http4k.contract.contract
import org.http4k.contract.div
import org.http4k.contract.meta
import org.http4k.contract.openapi.ApiInfo
import org.http4k.contract.openapi.v3.OpenApi3
import org.http4k.contract.openapi.v3.OpenApi3ApiRenderer
import org.http4k.contract.security.ApiKeySecurity
import org.http4k.core.Body
import org.http4k.core.Filter
import org.http4k.core.HttpHandler
import org.http4k.core.HttpTransaction
import org.http4k.core.Method
import org.http4k.core.Response
import org.http4k.core.Status.Companion.OK
import org.http4k.core.then
import org.http4k.core.with
import org.http4k.filter.CorsPolicy
import org.http4k.filter.ResponseFilters
import org.http4k.filter.ServerFilters
import org.http4k.lens.Path
import org.http4k.lens.Query
import <http://org.http4k.lens.int|org.http4k.lens.int>
import org.http4k.routing.bind
import org.http4k.routing.routes
import org.http4k.server.Jetty
import org.http4k.server.asServer
import java.time.Clock
class App {
val greeting: String
get() {
return "Hello world."
}
}
data class SumResult(val sum: Int)
val sumResponseBody = Body.auto<SumResult>().toLens()
fun main(args: Array<String>) {
fun add(value1: Int, value2: Int): HttpHandler = {
Response(OK).with(
sumResponseBody of SumResult(value1 + value2)
)
}
val filter: Filter = ResponseFilters.ReportHttpTransaction(Clock.systemUTC()) { tx: HttpTransaction ->
println(tx.labels.toString() + " took " + tx.duration)
}
val mySecurity = ApiKeySecurity(<http://Query.int|Query.int>().required("apiKey"), { it == 42 })
val contract = contract {
renderer = OpenApi3(ApiInfo("my great api", "v1.0"), Jackson, emptyList(), OpenApi3ApiRenderer(Jackson))
descriptionPath = "/docs/swagger.json"
security = mySecurity
routes += "/add" / <http://Path.int|Path.int>().of("value1") / <http://Path.int|Path.int>().of("value2") meta {
summary = "add"
description = "Adds 2 numbers together"
returning(OK, sumResponseBody to SumResult(55))
} bindContract Method.GET to ::add
}
val handler = routes(
"/context" bind filter.then(contract),
"/" bind contract {
renderer = OpenApi3(ApiInfo("my great super api", "v1.0"), Jackson, emptyList(), OpenApi3ApiRenderer(Jackson))
}
)
ServerFilters.Cors(CorsPolicy.UnsafeGlobalPermissive).then(handler).asServer(Jetty(8000)).start()
dave
02/23/2021, 4:39 PMrenderer = OpenApi3(ApiInfo("my great api", "v1.0"), OpenApiJackson, emptyList(), OpenApi3ApiRenderer(OpenApiJackson))
Elizabeth Thomas
02/23/2021, 4:40 PMrequired
in the components schemas objectdave
02/23/2021, 4:41 PMElizabeth Thomas
02/23/2021, 4:42 PMrequired
attribute in the component schemas?dave
02/23/2021, 4:44 PM"object-1725201476":
indicates that the renderer thinks that the backing object is JSON and not a Kotlin object"#/customPrefix/org.http4k.contract.openapi.v3.ArbObject2"
Elizabeth Thomas
02/23/2021, 4:48 PMdave
02/23/2021, 4:48 PMElizabeth Thomas
02/23/2021, 4:59 PMdave
02/23/2021, 4:59 PMElizabeth Thomas
02/23/2021, 4:59 PMdave
02/23/2021, 5:00 PMElizabeth Thomas
02/23/2021, 5:06 PMval contract = contract {
renderer = OpenApi3(ApiInfo("my great api", "v1.0"), Jackson, emptyList())//, OpenApi3ApiRenderer(Jackson))
descriptionPath = "/docs/swagger.json"
security = mySecurity
routes += "/add" / <http://Path.int|Path.int>().of("value1") / <http://Path.int|Path.int>().of("value2") meta {
summary = "add"
description = "Adds 2 numbers together"
returning(OK, sumResponseBody to SumResult(55))
} bindContract Method.GET to ::add
}
required
propertiesdave
02/23/2021, 5:07 PMElizabeth Thomas
02/23/2021, 5:07 PMdave
02/23/2021, 5:08 PMfun OpenApi3(apiInfo: ApiInfo, json: Jackson = Jackson, extensions: List<OpenApiExtension> = emptyList()) = OpenApi3(apiInfo, json, extensions, ApiRenderer.Auto(json, AutoJsonToJsonSchema(json)))
Elizabeth Thomas
02/23/2021, 5:12 PMdave
02/23/2021, 5:14 PMElizabeth Thomas
02/23/2021, 5:20 PMnon-auto renderer
?dave
02/23/2021, 5:23 PMOpenApi3ApiRenderer(Jackson)
is the bog standard renderer which doesn't support required fields. The one that does support it comes from ApiRenderer.Auto()
- that's the default that is used in the example if you click through (there are 2 ways to make an OpenApi3()
) - one in jacksonExt.kt and one in the class itselfElizabeth Thomas
02/24/2021, 3:51 AMHTTP ERROR 500 org.http4k.contract.openapi.v3.NoFieldFound: Could not find sum_value in SumResult(sumValue=55)
URI: /context/docs/swagger.json
STATUS: 500
MESSAGE: org.http4k.contract.openapi.v3.NoFieldFound: Could not find sum_value in SumResult(sumValue=55)
SERVLET: org.http4k.servlet.HttpHandlerServlet-438bad7c
CAUSED BY: org.http4k.contract.openapi.v3.NoFieldFound: Could not find sum_value in SumResult(sumValue=55)
Caused by:
org.http4k.contract.openapi.v3.NoFieldFound: Could not find sum_value in SumResult(sumValue=55)
at org.http4k.contract.openapi.v3.FieldRetrieval$Companion$compose$1.invoke(FieldRetrieval.kt:17)
at org.http4k.contract.openapi.v3.FieldRetrieval$Companion$compose$1.invoke(FieldRetrieval.kt:10)
at org.http4k.contract.openapi.v3.AutoJsonToJsonSchema.toObjectSchema(AutoJsonToJsonSchema.kt:94)
at org.http4k.contract.openapi.v3.AutoJsonToJsonSchema.toObjectOrMapSchema(AutoJsonToJsonSchema.kt:78)
at org.http4k.contract.openapi.v3.AutoJsonToJsonSchema.toSchema(AutoJsonToJsonSchema.kt:35)
at org.http4k.contract.openapi.v3.AutoJsonToJsonSchema.toSchema(AutoJsonToJsonSchema.kt:25)
at org.http4k.contract.openapi.ApiRenderer$Companion$Auto$fallbackSchema$1.toSchema(ApiRenderer.kt:30)
at org.http4k.contract.openapi.ApiRenderer$Companion$Auto$1.toSchema(ApiRenderer.kt)
at org.http4k.contract.openapi.v3.OpenApi3.toSchemaContent(OpenApi3.kt:202)
at org.http4k.contract.openapi.v3.OpenApi3.collectSchemas(OpenApi3.kt:140)
at org.http4k.contract.openapi.v3.OpenApi3.responses(OpenApi3.kt:132)
at org.http4k.contract.openapi.v3.OpenApi3.apiPath(OpenApi3.kt:106)
at org.http4k.contract.openapi.v3.OpenApi3.asPath(OpenApi3.kt:92)
at org.http4k.contract.openapi.v3.OpenApi3.description(OpenApi3.kt:68)
at org.http4k.contract.ContractRoutingHttpHandler$$special$$inlined$let$lambda$1.invoke(ContractRoutingHttpHandler.kt:66)
at org.http4k.contract.ContractRoutingHttpHandler$$special$$inlined$let$lambda$1.invoke(ContractRoutingHttpHandler.kt:26)
at org.http4k.routing.RouterMatch$MatchingHandler.invoke(Router.kt:47)
at org.http4k.routing.RouterMatch$MatchingHandler.invoke(Router.kt:46)
at org.http4k.core.Http4kKt$NoOp$1$1.invoke(Http4k.kt:11)
at org.http4k.core.Http4kKt$NoOp$1$1.invoke(Http4k.kt)
at org.http4k.core.Http4kKt$NoOp$1$1.invoke(Http4k.kt:11)
at org.http4k.core.Http4kKt$NoOp$1$1.invoke(Http4k.kt)
at org.http4k.core.Http4kKt$NoOp$1$1.invoke(Http4k.kt:11)
at org.http4k.core.Http4kKt$NoOp$1$1.invoke(Http4k.kt)
at org.http4k.filter.ResponseFilters$ReportHttpTransaction$invoke$2$1.invoke(ResponseFilters.kt:48)
at org.http4k.filter.ResponseFilters$ReportHttpTransaction$invoke$2$1.invoke(ResponseFilters.kt:40)
at org.http4k.filter.ServerFilters$Cors$invoke$1$1.invoke(ServerFilters.kt:55)
at org.http4k.filter.ServerFilters$Cors$invoke$1$1.invoke(ServerFilters.kt:50)
at org.http4k.contract.ContractRoutingHttpHandler$identify$1$1$1.invoke(ContractRoutingHttpHandler.kt:105)
at org.http4k.contract.ContractRoutingHttpHandler$identify$1$1$1.invoke(ContractRoutingHttpHandler.kt:26)
at org.http4k.core.Http4kKt$then$2.invoke(Http4k.kt:15)
at org.http4k.core.Http4kKt$then$2.invoke(Http4k.kt)
at org.http4k.routing.RouterMatch$MatchingHandler.invoke(Router.kt:47)
at org.http4k.routing.RouterMatch$MatchingHandler.invoke(Router.kt:46)
at org.http4k.routing.RouterBasedHttpHandler.invoke(RouterBasedHttpHandler.kt:23)
at org.http4k.routing.RouterBasedHttpHandler.invoke(RouterBasedHttpHandler.kt:13)
at org.http4k.servlet.Http4kServletAdapter.handle(Http4kServletAdapter.kt:19)
at org.http4k.servlet.HttpHandlerServlet.service(HttpHandlerServlet.kt:14)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:750)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:761)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:517)
at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:226)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1576)
at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:226)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1358)
at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:181)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:472)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1549)
at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:179)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1282)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:134)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
at org.eclipse.jetty.server.Server.handle(Server.java:567)
at org.eclipse.jetty.server.HttpChannel.lambda$handle$0(HttpChannel.java:404)
at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:661)
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:396)
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:289)
at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:324)
at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:105)
at org.eclipse.jetty.io.SocketChannelEndPoint$1.run(SocketChannelEndPoint.java:106)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:790)
at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:912)
at java.base/java.lang.Thread.run(Thread.java:834)
data class SumResult(val sumValue: Int)
from data class SumResult(val sum: Int)
. I get the following error when I navigate to <http://localhost:8000/context/docs/swagger.json>
json
in OpenApi3
call expects the Kotlin data class member variables to be in snake_case?dave
02/24/2021, 5:03 PMElizabeth Thomas
02/24/2021, 5:32 PMobject Jackson : ConfigurableJackson(
ObjectMapper()
.registerModule(KotlinModule())
.setDefaultPropertyInclusion(JsonInclude.Include.NON_NULL)
.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)
.configure(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE, false)
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.configure(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL, true)
.configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY, true)
.configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS, true)
.setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE))
data class SumResult(val sumValue: Int)
val sumResponseBody = Body.auto<SumResult>().toLens()
org.http4k.contract.openapi.v3.NoFieldFound: Could not find sum_value in SumResult(sumValue=55)
dave
02/24/2021, 5:33 PMElizabeth Thomas
02/24/2021, 5:33 PMsum_value
is what is being looked for.. not sumValue
from my data class definitionorg.http4k.contract.openapi.v3.NoFieldFound: Could not find sum_value in SumResult(sumValue=55)
at org.http4k.contract.openapi.v3.FieldRetrieval$Companion$compose$1.invoke(FieldRetrieval.kt:17)
at org.http4k.contract.openapi.v3.FieldRetrieval$Companion$compose$1.invoke(FieldRetrieval.kt:10)
at org.http4k.contract.openapi.v3.AutoJsonToJsonSchema.toObjectSchema(AutoJsonToJsonSchema.kt:94)
at org.http4k.contract.openapi.v3.AutoJsonToJsonSchema.toObjectOrMapSchema(AutoJsonToJsonSchema.kt:78)
at org.http4k.contract.openapi.v3.AutoJsonToJsonSchema.toSchema(AutoJsonToJsonSchema.kt:35)
at org.http4k.contract.openapi.v3.AutoJsonToJsonSchema.toSchema(AutoJsonToJsonSchema.kt:25)
at org.http4k.contract.openapi.ApiRenderer$Companion$Auto$fallbackSchema$1.toSchema(ApiRenderer.kt:30)
at org.http4k.contract.openapi.ApiRenderer$Companion$Auto$1.toSchema(ApiRenderer.kt)
at org.http4k.contract.openapi.v3.OpenApi3.toSchemaContent(OpenApi3.kt:202)
at org.http4k.contract.openapi.v3.OpenApi3.collectSchemas(OpenApi3.kt:140)
at org.http4k.contract.openapi.v3.OpenApi3.responses(OpenApi3.kt:132)
at org.http4k.contract.openapi.v3.OpenApi3.apiPath(OpenApi3.kt:106)
at org.http4k.contract.openapi.v3.OpenApi3.asPath(OpenApi3.kt:92)
at org.http4k.contract.openapi.v3.OpenApi3.description(OpenApi3.kt:68)
at org.http4k.contract.ContractRoutingHttpHandler$$special$$inlined$let$lambda$1.invoke(ContractRoutingHttpHandler.kt:66)
at org.http4k.contract.ContractRoutingHttpHandler$$special$$inlined$let$lambda$1.invoke(ContractRoutingHttpHandler.kt:26)
at org.http4k.routing.RouterMatch$MatchingHandler.invoke(Router.kt:47)
at org.http4k.routing.RouterMatch$MatchingHandler.invoke(Router.kt:46)
at org.http4k.core.Http4kKt$NoOp$1$1.invoke(Http4k.kt:11)
at org.http4k.core.Http4kKt$NoOp$1$1.invoke(Http4k.kt)
at org.http4k.core.Http4kKt$NoOp$1$1.invoke(Http4k.kt:11)
at org.http4k.core.Http4kKt$NoOp$1$1.invoke(Http4k.kt)
at org.http4k.core.Http4kKt$NoOp$1$1.invoke(Http4k.kt:11)
at org.http4k.core.Http4kKt$NoOp$1$1.invoke(Http4k.kt)
at org.http4k.filter.ResponseFilters$ReportHttpTransaction$invoke$2$1.invoke(ResponseFilters.kt:48)
at org.http4k.filter.ResponseFilters$ReportHttpTransaction$invoke$2$1.invoke(ResponseFilters.kt:40)
at org.http4k.filter.ServerFilters$Cors$invoke$1$1.invoke(ServerFilters.kt:55)
at org.http4k.filter.ServerFilters$Cors$invoke$1$1.invoke(ServerFilters.kt:50)
at org.http4k.contract.ContractRoutingHttpHandler$identify$1$1$1.invoke(ContractRoutingHttpHandler.kt:105)
at org.http4k.contract.ContractRoutingHttpHandler$identify$1$1$1.invoke(ContractRoutingHttpHandler.kt:26)
at org.http4k.core.Http4kKt$then$2.invoke(Http4k.kt:15)
at org.http4k.core.Http4kKt$then$2.invoke(Http4k.kt)
at org.http4k.routing.RouterMatch$MatchingHandler.invoke(Router.kt:47)
at org.http4k.routing.RouterMatch$MatchingHandler.invoke(Router.kt:46)
at org.http4k.routing.RouterBasedHttpHandler.invoke(RouterBasedHttpHandler.kt:23)
at org.http4k.routing.RouterBasedHttpHandler.invoke(RouterBasedHttpHandler.kt:13)
at org.http4k.servlet.Http4kServletAdapter.handle(Http4kServletAdapter.kt:19)
at org.http4k.servlet.HttpHandlerServlet.service(HttpHandlerServlet.kt:14)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:750)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:761)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:517)
at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:226)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1576)
at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:226)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1358)
at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:181)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:472)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1549)
at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:179)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1282)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:134)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
at org.eclipse.jetty.server.Server.handle(Server.java:567)
at org.eclipse.jetty.server.HttpChannel.lambda$handle$0(HttpChannel.java:404)
at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:661)
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:396)
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:289)
at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:324)
at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:105)
at org.eclipse.jetty.io.SocketChannelEndPoint$1.run(SocketChannelEndPoint.java:106)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:790)
at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:912)
at java.base/java.lang.Thread.run(Thread.java:834)
dave
02/24/2021, 5:36 PMElizabeth Thomas
02/24/2021, 5:36 PMPropertyNamingStrategy
as LOWER_CAMEL_CASE
instead of SNAKE_CASE
, the openApi spec generates correctlydave
02/24/2021, 5:38 PMElizabeth Thomas
02/24/2021, 5:38 PMdave
02/24/2021, 5:40 PMElizabeth Thomas
02/24/2021, 5:41 PMdave
02/24/2021, 5:42 PMElizabeth Thomas
02/24/2021, 5:43 PMrequired
meta data on the component schemas?dave
02/24/2021, 5:44 PMfun OpenApi3(apiInfo: ApiInfo, json: Jackson = Jackson, extensions: List<OpenApiExtension> = emptyList()) = OpenApi3(apiInfo, json, extensions, ApiRenderer.Auto(json, AutoJsonToJsonSchema(json)))
fun AutoJsonToJsonSchema(json: Jackson) = AutoJsonToJsonSchema(
json,
FieldRetrieval.compose(
SimpleLookup(metadataRetrievalStrategy = JacksonFieldMetadataRetrievalStrategy),
FieldRetrieval.compose(JacksonJsonPropertyAnnotated, JacksonJsonNamingAnnotated(json))
)
)
Elizabeth Thomas
02/24/2021, 5:45 PMrenderer
and OpenApi3Renderer
. Is there a way to use OpenApi3
from jacksonExt.kt instead of a similar function from OpenApi3.kt?dave
02/24/2021, 6:04 PMOpenApi3(apiInfo, json, extensions, ApiRenderer.Auto(json, AutoJsonToJsonSchema(json)))