-
Notifications
You must be signed in to change notification settings - Fork 42
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
sealed class support #5
Comments
indeed you should have a warning in the log |
@Wicpar Ah yeah, that would be great indeed. I gave it a quick try by adding to
and it does now show the classes in the swagger UI. But this was a complete blind stab, so not sure if that makes complete sense and also not sure if that is the best way to display it in the UI. So if you could take a look that would be really appreciated. |
@Globegitter private fun SchemaRegistrar.makeObjectSchema(type: KType): Schema<*> {
val erasure = type.jvmErasure
if (erasure.isSealed) {
return Schema.OneSchemaOf(erasure.sealedSubclasses.map { get(it.starProjectedType).schema })
}
val props = erasure.declaredMemberProperties.filter { it.visibility == KVisibility.PUBLIC }
val properties = props.associate {
Pair(it.name, get(it.returnType).schema)
}
if (properties.isEmpty()) log.warn("No public properties found in object $type")
return Schema.SchemaObj<Any>(
properties,
props.filter { !it.returnType.isMarkedNullable }.map { it.name })
} it works with the description, but jackson is not able to parse it properly through This implementation supports circular definitions in the model. |
Ah yeah, that is already looking much better - thanks. I am not sure I fully understand the comment |
Do you simply send object based on a subclass or also want to receive them? |
I do want to receive them, i.e. this is the request json for a post endpoint. But I have tried this change and at least in my unit test it is working fine with sending the json as a string and me receiving it as the correct object. |
In my tests: ...
route("sealed") {
post<Unit, Base, Base>(
info("Sealed class Endpoint", "This is a Sealed class Endpoint"),
exampleRequest = Base.A("Hi"),
exampleResponse = Base.A("Hi")
) { params, base ->
respond(base)
}
}
...
sealed class Base {
data class A(val str: String) : Base()
data class B(val i: Int) : Base()
data class C(val l: Long) : Base()
}
does not work when receiving a json request body that is A, B, or C. |
You would have to add e.g.: @JsonTypeInfo(use = JsonTypeInfo.Id.NAME)
sealed class Base {
data class A(val str: String) : Base()
data class B(val i: Int) : Base()
data class C(val l: Long) : Base()
} and then make sure the json contains an extra And make sure to use jackson 2.10.1 |
i got it to work with: @JsonTypeInfo(use = JsonTypeInfo.Id.NAME)
@JsonSubTypes(
JsonSubTypes.Type(Base.A::class, name = "a"),
JsonSubTypes.Type(Base.B::class, name = "b"),
JsonSubTypes.Type(Base.C::class, name = "c")
)
sealed class Base {
class A(val str: String) : Base()
class B(val i: Int) : Base()
class C(val l: Long) : Base()
}
|
i have pushed the modifications. |
Hey, thanks for this project, so far it looks great but I am running into some limitations with sealed classes. I have a model as follows:
where-as app is a sealed class and while jackson 2.10.1 recognises that and converts incoming requests perfectly fine in the generated json schema
App
is only displayed as an empty object. Are sealed classes meant to be supported? As far as I can tell that would probably map to a oneof, right?Edit: For reference, here is btw the PR that added auto-discovery of sealed classes: FasterXML/jackson-module-kotlin#240
The text was updated successfully, but these errors were encountered: