-
Notifications
You must be signed in to change notification settings - Fork 28
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
fix: ignore __type when deserializing union for AWS Json protocols #964
Conversation
* in a tag called "boo", pass an instance of XmlList to the FieldDescriptor of `XmlList(elementName="boo")`. | ||
*/ | ||
@InternalApi | ||
public interface FieldTrait |
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.
Why are these moved?
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.
Since the file was named SdkFieldDescriptor
I thought it would make more sense to have field traits in a different place, I can change it to how it was though
* | ||
*/ | ||
@InternalApi | ||
public data class IgnoreKey(public val key: String, public val regardlessOfInModel: Boolean = true) : FieldTrait |
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 should be in serde-json
as it only applies there right? (see JsonFieldTraits.kt
)
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.
Question: Why do we need regardlessOfInModel
, I would assume if we set IgnoreKey
as a trait on the object descriptor it's going to be ignored regardless of whether it's modeled. This seems unnecessary to me but I'd like to understand what the motivation was.
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.
I was thinking of a case where we have a union with a member called __type
. If that happens we would not deserialize that member, because we're ignoring that key regardless of what the model says. The default is true anyway so it behaves as expected unless set explicitly to false.
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.
I didn't put it in a JSON specific file because I think this might be useful in the future for other deserializers like the XML one. I don't know if we have a use case already but that was my reasoning behind 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.
What do you think? Should regardlessOfInModel
stay? Is this something that could be useful elsewhere?
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.
I was thinking of a case where we have a union with a member called __type. If that happens we would not deserialize that member, because we're ignoring that key regardless of what the model says
Shouldn't this just be a choice by codegen though? If we want it deserialized because it's in the model don't add the IgnoreKey
trait.
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.
I didn't put it in a JSON specific file because I think this might be useful in the future for other deserializers like the XML one. I don't know if we have a use case already but that was my reasoning behind it.
YAGNI probably. Also IgnoreKey
was a suggestion for the name based on JSON objects are "keyed". The same isn't really true of XML.
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.
That makes sense but the issue this is trying to solve: smithy-lang/smithy#1945
is that sometimes a unnecessary __type
is serialized. What you're suggesting is to always ignore __type
. But there could be a cases where __type
could be in the model and we would be ignoring it because sometimes there's an extra one there unnecessarily
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.
What you're suggesting is to always ignore __type. But there could be a cases where __type could be in the model and we would be ignoring it because sometimes there's an extra one there unnecessarily
I don't follow, if __type
is in the model and we want to deserialize it then just don't emit the IgnoreKey
trait during codegen. What am I missing here?
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.
I guess that logic could live in codegen, now it's in the deserializer
class JsonDeserializerIgnoresKeysTest { | ||
class IgnoresKeysTest { |
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 double-nested class seems unnecessary, I think you can just declare these at the top-level without using a companion object
for simplicity
val X_DESCRIPTOR = SdkFieldDescriptor(SerialKind.Integer, JsonSerialName("x")) | ||
val Y_DESCRIPTOR = SdkFieldDescriptor(SerialKind.Integer, JsonSerialName("y")) | ||
val Z_DESCRIPTOR = SdkFieldDescriptor(SerialKind.Integer, JsonSerialName("z")) |
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.
duplicated, can re-use the others descriptors above
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.
Looks good overall!
@@ -198,7 +198,13 @@ private class JsonFieldIterator( | |||
val token = reader.nextTokenOf<JsonToken.Name>() | |||
val propertyName = token.value | |||
val field = descriptor.fields.find { it.serialName == propertyName } | |||
field?.index ?: Deserializer.FieldIterator.UNKNOWN_FIELD | |||
|
|||
if (descriptor.traits.contains(IgnoreKey(propertyName))) { |
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.
Style: Consider if (IgnoreKey(propertyName) in descriptor.traits)
private val Y_DESCRIPTOR = SdkFieldDescriptor(SerialKind.Integer, JsonSerialName("y")) | ||
private val Z_DESCRIPTOR = SdkFieldDescriptor(SerialKind.Integer, JsonSerialName("z")) | ||
private val OBJ_DESCRIPTOR = SdkObjectDescriptor.build { | ||
trait(IgnoreKey("z")) // <---- |
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.
Question: What does the comment // <----
mean? Same question on L120-121.
shape: Shape, | ||
members: List<MemberShape>, | ||
writer: KotlinWriter, | ||
): JsonSerdeDescriptorGenerator = JsonSerdeDescriptorGenerator(ctx.toRenderingContext(protocolGenerator, shape, writer), members, supportsJsonNameTrait) |
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.
Style: Line length > 120 chars
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.
Looks good, one suggestion but otherwise approved.
import kotlin.test.Test | ||
import kotlin.test.assertEquals | ||
|
||
class JsonDeserializerIgnoresKeysTest { |
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.
Suggestion: Every test has explicitly modeled field descriptors. You're missing coverage for unmodeled fields that we want to skip rather than enumerate as unknown.
SonarCloud Quality Gate failed. 0 Bugs No Coverage information Catch issues before they fail your Quality Gate with our IDE extension SonarLint |
Issue #
closes aws-sdk-kotlin#1044
Description of changes
-Added
IgnoreKey
trait and adaptedJsonDeserializer
to itBy submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.