-
Notifications
You must be signed in to change notification settings - Fork 43
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
Support for Kotlin Serialization #327
Conversation
and add basic support for Kotlinx Serialization
ad489c7
to
e410879
Compare
Expose UUID and URI as string as native Kotlin type do not exist
@cjbooms Since this is a new feature, I am thinking that once you (and possibly others) have reviewed the implementation, it will be beneficial to get feedback from people that make use of Kotlin Serialization in their projects - both backend and mobile. Since it does not change existing code generation output I think we can safely be released once we are happy with the implementation. Possibly as a "beta" release, if you are more comfortable with that. |
Nice work, this will be a great addition. I look forward to reviewing this tomorrow or the next day. Yeah, I'm not worried about doing anything special for release. Let's just throw it out there and see what the feedback is. We're not going to break anyone, and can easily improve things in future releases as it gets used. |
It is worth noting that, due to the requirement of serializers being present at compile time, the generated Event does actually not compile. This is due to the untyped object In order for this to work, we need to annotate I have made a PoC over here, but it requires polishing before being mergeable. It does not have to block this PR, but it is useful info to have in the review process. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work. Impressed with how little impact on the existing generation code structures you managed to achieve.
A few nit picks and clarifications for my own benefit, but I'm happy to release and get community feedback if that's what you want.
@@ -67,13 +68,15 @@ import java.io.Serializable | |||
import java.net.MalformedURLException | |||
import java.net.URL | |||
|
|||
class JacksonModelGenerator( | |||
class JacksonModelGenerator( // TODO: Rename to ModelGenerator |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Go for it!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 Will do in a PR once this has been merged.
import com.squareup.kotlinpoet.TypeName | ||
import com.squareup.kotlinpoet.TypeSpec | ||
|
||
sealed interface SerializationAnnotations { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a nice abstraction. I can imagine you had lots of nasty branching logic before you introduced it. kudos
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
} | ||
OasType.DateTime -> { | ||
if (MutableSettings.serializationLibrary() == KOTLINX_SERIALIZATION) KotlinxInstant | ||
else getOverridableDateTimeType() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does kotlinx only have one date-time, or may we also need an overridable function for it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's only one and you would normally use Instant
for datetimes and thus no need for overrides ✌️
public val entityId: String, | ||
@SerialName("data") | ||
@get:NotNull | ||
public val `data`: Map<String, Any?>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wrt your pre-review comment around @Contextual, are we being inconsistent by generating this, but omitting additional properties? I'm wondering would it be better to error out, rather than produce code that:
a.) Doesn't compile
b.) Results in data loss (is it possible that kotlinx will quietly drop additional properties?)
Or maybe we should add the annotation to give the user a better hint to implement the required serializer?
Also, do you have any idea if there is a KotlinX issue we can track for this feature to be natively supported?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lets be consistent and error out in case untyped objects or additional properties are found in the schema. I have added this to the PR.
Supporting untyped objects with @Contextual
is totally viable, but we need to figure out how to build it in a user friendly way.
Support for additionalProperties is being tracked in this issue by @pschichtel.
additional properties not supported
We might be able to support them in the future by annotating Any with @contextual
@cjbooms Thanks for performing an initial review 🙏 Once you’ve had a chance to go through the changes, I’d love to get this released so we can hear what the community thinks. |
This PR builds on the ideas in #249 (tracked in #89) to introduce support for kotlinx.serialization (KxS) annotations on the generated models.
A new
--serialization-library
option allows the user to choose betweenJACKSON
andKOTLINX_SERIALIZATION
.The Jackson implementation is the default and has not changed, and users will get the same output as previously.
For date and datetime kotlinx-datetime is used to make the generated code work in multi platform / non-JVM environments. Date is translated to
kotlinx.datetime.LocalDate
and datetime tokotlinx.datetime.Instant
.Unsupported features
additionalProperties: true
is not supported. This is due to fact that supporting amap<String,Any?>
is quite tricky (if at all possible?) with Kotlinx.Serialization, whereas Jackson hasJsonAnyGetter
/JsonAnySetter
to support this.We might be able to configure the property with @Contextual to instruct the plugin to resolve serializer at runtime.
Related: Support for additional properties Kotlin/kotlinx.serialization#1978.
number
without format is currently translated to Java'sBigDecimal
which will not work in non-JVM Kotlin. Works fine fornumber
/float
andnumber
/double
as these are translated into Kotlin types.Tests
I am unsure how many more tests for the examples we want. Many of the examples are concerned with translating OpenAPI into models, and are not specific to the serialization annotations. Any opinions/input/suggestion are welcome.
TODO
JacksonModelGenerator
to simplyModelGenerator
(in future PR).