Skip to content
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

Ability to enforce @SerialName annotation on all sealed class inheritors #1950

Open
maxdroz opened this issue May 25, 2022 · 4 comments
Open
Labels

Comments

@maxdroz
Copy link

maxdroz commented May 25, 2022

What is your use-case and why do you need this feature?
Default class discriminator value right now is full class name.
This value is stored in serialized json.
Class name could (and will) be changed independently of it's serialized value.

This means that if class would be renamed, or even more probably, moved to another package, all previously serialized jsons will no longer be unserializable.
Old jsons would still contain old class name, which, now, would be unrecognized.

Describe the solution you'd like
Ability to enforce @SerialName annotation on all sealed class inheritors.

Convenience of autogenerated class discriminators comes with a cost of being easily breakable with simple refactoring.
While it is understandable to be careful with class names of serialized objects (same way we should be careful with their variable names), being careful with package name is not something obvious.

If it would be possible to enforce @SerialName via flag in plugin, this issue can be fully solved, as the only way to break something, would be consciously changing @SerialName of a class. And not by renaming package, which somewhere deep inside contains @Serializable class, that relies on package name.

@sandwwraith
Copy link
Member

Your arguments are understandable and valid. However, why it should be only for sealed class inheritors? All classes would suffer from this problem, both sealed and open-polymorphic. Such logic is also valid for properties that can be renamed, too.

In an ideal world, every property & class should have its own stable name. However, it would be too much hassle to require specifying these names explicitly.

@maxdroz
Copy link
Author

maxdroz commented Jun 1, 2022

I guess this feature is fully applicable for open-polymorphic classes too. I just didn't personally had a use case for it and haven't thought about it.

I fully understand and agree that we should cut corners by not specifying serial name for properties and taking it from property name. But discriminator is different. It does not only include name of class, it also includes package name.
Which this is counter-intuitive. And very non implicit.

I get that class name and class property names are used in serialization and that changing them will break something, but I don't think that's it's intuitive that you can break serialization by not even modifying file, just it's location

@elizarov
Copy link
Contributor

elizarov commented Jun 1, 2022

IMO, the most common cause if that you want the names to be without the package. This should be covered by another feature to specify a strategy on dealing with serial names of classes, similar to request #33 for fields.

@dshatz
Copy link

dshatz commented Dec 22, 2022

I think it would be useful to provide a way to inherit @SerialName from parent class properties.
My usecase:

@Serializable
data class Order(
    override val amount: Int = 0
    // other properties
): IOrder

interface IOrder {
  @SerialName("doc_amount") val amount: Int
}

Now, when serializing Order, amount field should be serialized as doc_amount and not as amount. Please advise if this is currently possible without specifying @SerialName on property of the child class. It can get quite repetetive if there are a lot subclasses.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants