Closed jwinger-intel closed 10 months ago
Not sure how hard this would be to implement, but in CustomSchemas
another method like:
install(SwaggerUI) {
customSchemas {
// Blah, make all the regular customs
// ...
refKey = includeClass<List<Foo>>()
}
}
It would be totally awesome and fix my issue.
I think it would take an extra member in the CustomSchema
config that can be pulled by the SchemaContext.finalize
. I'm working on some other stuff right now, but might try to submit a patch in the next couple days.
Hi, you are right, the schemas are not getting added to the spec, because they aren't used in any route.
I think another possible quick fix for your situation could be to allow generating all custom schemas, no matter if they are used or not (maybe as a toggle in the plugin-config).
However, imho a future-proof solution would be a proper support of "oneOf" and not just for custom schemas. Maybe with a syntax like this ... ?
body(anyOf(TypeA::class, TypeB::class)) {
//...
}
I'll try looking into this aswell 👍
I think another possible quick fix for your situation could be to allow generating all custom schemas, no matter if they are used or not (maybe as a toggle in the plugin-config)
Hi @SMILEY4, how would that quickfix look like?
fyi: I also realized that the schemaEncoder only overwrites 'used' Types but I managed to configure the schema-builder to serialize my OffsetDateTimes with the '$ref'-field and point it to '#/components/schemas/DateTime'. But unfortunately my customSchema is not merged into the oas:
here my code
customSchemas {
// https://github.com/SMILEY4/ktor-swagger-ui/wiki/Request-and-Response-Bodies-Custom-Schemas#defining-custom-schemas
json("DateTime") {
"""
{
"type": "string",
"format": "date-time",
"description: "A timestamp as defined by RFC 3339, section 5.6.",
"example: "2017-07-21T17:32:28Z"
}
""".trimIndent()
}
}
encoding {
EncodingConfig.DEFAULT_SCHEMA_GENERATOR = SchemaGenerator(
schemaGeneratorConfigBuilder().also {
it.forTypesInGeneral()
.withTypeAttributeOverride { objectNode: ObjectNode, typeScope: TypeScope, _: SchemaGenerationContext ->
if (typeScope.type.erasedType == OffsetDateTime::class.java) {
objectNode
.put("\$ref", "#/components/schemas/DateTime")
}
}
} .build()
)
}
Currently, the plugin iterates over all configured routes and extracts the used schemas from the documentation-block. So for example, this ...
install(SwaggerUI) {
customSchemas {
json("customModel") { "..." }
}
}
post("pets", {
request {
body<NewPet>()
}
response {
HttpStatusCode.OK to {
body<Pet>()
}
}
}) {
// handle request ...
}
... would only generate and add schemas for NewPet
and Pet
, not for customModel
since its not referenced in any route. Same with your example. DateTime
is not used anywhere (it does not parse the $ref-fields) so its not included.
My proposed quick solution would be to add a flag e.g. "alwaysInclude " in the plugin-config like this:
install(SwaggerUI) {
customSchemas {
alwaysInclude = true
json("customModel") { "..." }
}
}
post("pets", {
request {
body<NewPet>()
}
response {
HttpStatusCode.OK to {
body<Pet>()
}
}
}) {
// handle request ...
}
... which would result in all custom schemas in to be always added to the spec, no matter if used in any route or not. This would result in the custom customModel
-Schema (or DateTime
in your example) to be added at #/components/schemas/customModel
(or #/components/schemas/DateTime
).
refined api for simple body-schema-customization with version 2.6.0
Hey! Loving the library, but running into a a problem.
One of my backend's return types can be a list containing one of 3 different parameterized types (
List<Wrap<A>>, List<Wrap<B>>, ...
). From my understanding the final OpenAPI type would be something like:I'm having trouble defining that reasonably with the library.
I've tried a bunch of stuff, but right now I'm trying to define using the
CustomSchemas
config. I'm self-creating the list as a OpenAPISchema
object fine, and I can set the reference. But I can't figure out how to establish the definitions forWrap<T>
. That object isn't used anywhere else, so it doesn't get auto-populated by the generator. If I add the definitions to theCustomSchemas
config, they're not directly referenced by a request/response so it seems like they don't get populated because it's assumed that custom schemas are self-contained.Here's roughly what I'm doing now:
The output I get. There are no entries in
#/components/schemas
for anyWrap
objects.Am I going about this all wrong? I don't see any way to force schemas to be instantiated, and I don't really want to have to build the whole type in the CustomSchema def or create dummy endpoints to have the objects recognized. Having the refs to the smaller objects is nice.
Also, I just noticed that body types generate different component paths depending on if they are in a list:
Maybe due to the underlying Library?