Open rgmz opened 3 years ago
did you look at https://vertx.io/docs/vertx-core/kotlin/#_data_objects_builders ?
Yes, that's what I was referring to by ...Of
methods.
Those are useful for constructing Java data objects in Kotlin but, in my experience, aren't as compelling or reliable for generating Kotlin data objects.
I've opened two issues relating to the codegen of these builders (#158,
idiosyncrasies. That said, fixing those wouldn't address the larger pain points, like builders requiring a no-arg constructor.
Fundamentally, the issue is that DataObject constraints (and utilities) aren't compatible with Kotlin's data classes, which are a core language feature. That's a huge pain point, and I'd like to see how/if we can improve the experience.
P.S., Are there plans to support Java Records? If so, those would face similar challenges.
On Mon., May 31, 2021, 9:21 a.m. Julien Viet, @.***> wrote:
did you look at https://vertx.io/docs/vertx-core/kotlin/#_data_objects_builders ?
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/vert-x3/vertx-lang-kotlin/issues/198#issuecomment-851487927, or unsubscribe https://github.com/notifications/unsubscribe-auth/AHVFC7RWQT4JQMPMTSAWIBTTQOEMDANCNFSM4523Y5EA .
Description
Presently, there are a few issues which make Kotlin Data Classes incompatible/difficult to use with Vert.x's
@DataObject
code generation (e.g. #17, #43).For example, instead of using data classes idiomatically:
you're forced to write code which is significantly lengthier and less 'safe': can be instantiated without all parameters, parameters are defined with mutable
var
instead ofval
, etc.:From what I recall, the two main sources of ire are:
Required
JsonObject
constructorUnlike Java, [secondary constructors in Kotlin must call the primary constructor](https ://kotlinlang.org/docs/classes.html#secondary-constructors) :
Required no-arg constructor (for the generated converter and
...Of
methods)As mentioned above, data classes must be instantiated with all the required parameters. That constraint makes them incompatible with the generated
Converter.fromJson
methods, as that requires the class to be instantiated, and the properties to be mutible:It also makes them incompatible with the generated
yourTypeOf(...
) methods, which similarly requires the class to be instantiated before it can populate values: https://github.com/vert-x3/vertx-lang-kotlin/blob/ae327c43acdd6cb40d0d606b46cedd39f646d352/vertx-lang-kotlin/src/main/kotlin/io/vertx/kotlin/pgclient/PgConnectOptions.kt#L148-L152Solutions
With everything I previously mentioned in mind, what can we do to improve the experience?
Some ideas off the top of my head:
@ConstructorBinding
Spring Boot introduced the@ConstructorBinding
annotation, which eliminates the need for a no-arg constructor :I'm not sure the feasibility of implementing something like this, as it's presumably dynamic and could lead to security issues. Neverthless, I'm including it here for inspiration.
Static
@JsonCreator
method In Jackson, you can define a static method annotated with@JsonCreator
, which will be used to instantiate the class:This could be an alternative to the
JsonObject
constructor, and mitigate having to stuff values into thethis()
block.Kotlinx.Serialization Kotlinx.Serialization is a native serialization library which generates encodes and decoders at compile time.
Perhaps we could leverage kotlinx.serialization to generate safe encoders and decoders?
Custom Codegen We could augment
vertx-lang-kotlin-gen
, or write a Kotlin Compiler Plugin, to generate Kotlin-friendly converters and...Of
methods.