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?Elizabeth Thomas
02/20/2021, 11:00 AMdave
02/20/2021, 11:05 AMdave
02/20/2021, 11:06 AMdave
02/20/2021, 11:07 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()
}
Elizabeth Thomas
02/23/2021, 3:46 PMlocalhost: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"
}
}
}
}
Elizabeth Thomas
02/23/2021, 3:47 PMcomponents.schemas.object-1725201476
, required
comes back as []
even though my data class SumResult
has sum
property as not nullable.Elizabeth Thomas
02/23/2021, 3:48 PMobject 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)
Elizabeth Thomas
02/23/2021, 3:49 PMrequired
field to be filled with non-nullable properties of my response object in my exampledave
02/23/2021, 4:03 PMdave
02/23/2021, 4:04 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 PMElizabeth Thomas
02/23/2021, 4:09 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 PMdave
02/23/2021, 4:34 PMdave
02/23/2021, 4:34 PMdave
02/23/2021, 4:36 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)
)
Elizabeth Thomas
02/23/2021, 4:39 PMpackage 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 PMdave
02/23/2021, 4:41 PMElizabeth Thomas
02/23/2021, 4:42 PMrequired
attribute in the component schemas?Elizabeth Thomas
02/23/2021, 4:44 PMdave
02/23/2021, 4:44 PMdave
02/23/2021, 4:45 PMdave
02/23/2021, 4:45 PMdave
02/23/2021, 4:46 PM"object-1725201476":
indicates that the renderer thinks that the backing object is JSON and not a Kotlin objectdave
02/23/2021, 4:46 PM"#/customPrefix/org.http4k.contract.openapi.v3.ArbObject2"
dave
02/23/2021, 4:47 PMElizabeth Thomas
02/23/2021, 4:48 PMdave
02/23/2021, 4:48 PMdave
02/23/2021, 4:58 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
}
Elizabeth Thomas
02/23/2021, 5:06 PMrequired
propertiesdave
02/23/2021, 5:07 PMdave
02/23/2021, 5:07 PMdave
02/23/2021, 5:07 PMElizabeth Thomas
02/23/2021, 5:07 PMElizabeth Thomas
02/23/2021, 5:08 PMdave
02/23/2021, 5:08 PMdave
02/23/2021, 5:09 PMdave
02/23/2021, 5:09 PMfun OpenApi3(apiInfo: ApiInfo, json: Jackson = Jackson, extensions: List<OpenApiExtension> = emptyList()) = OpenApi3(apiInfo, json, extensions, ApiRenderer.Auto(json, AutoJsonToJsonSchema(json)))
dave
02/23/2021, 5:09 PMdave
02/23/2021, 5:09 PMdave
02/23/2021, 5:09 PMElizabeth Thomas
02/23/2021, 5:12 PMElizabeth Thomas
02/23/2021, 5:14 PMdave
02/23/2021, 5:14 PMdave
02/23/2021, 5:19 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 itselfdave
02/23/2021, 5:24 PMElizabeth 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)
Elizabeth Thomas
02/24/2021, 3:51 AMdata 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>
Elizabeth Thomas
02/24/2021, 3:52 AMElizabeth Thomas
02/24/2021, 5:02 PMjson
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))
Elizabeth Thomas
02/24/2021, 5:32 PMdata class SumResult(val sumValue: Int)
val sumResponseBody = Body.auto<SumResult>().toLens()
Elizabeth Thomas
02/24/2021, 5:33 PMorg.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 definitionElizabeth Thomas
02/24/2021, 5:34 PMorg.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 PMdave
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 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 PMdave
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))
)
)
dave
02/24/2021, 5:44 PMdave
02/24/2021, 5:45 PMElizabeth Thomas
02/24/2021, 5:45 PMElizabeth Thomas
02/24/2021, 5:45 PMElizabeth Thomas
02/24/2021, 5:58 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)))