aws / aws-sdk-java-v2

The official AWS SDK for Java - Version 2
Apache License 2.0
2.16k stars 833 forks source link

DynamoDB Enhanced: Support schema mixins #5375

Open chrylis opened 2 months ago

chrylis commented 2 months ago

Describe the feature

For classes that for whatever reason cannot carry Jackson annotations directly, Jackson supports defining a "mixin" interface that mirrors the properties of the class and has the desired annotations. It would be helpful if the Enhanced client had a similar capability.

Use Case

I have a number of data classes that are defined in client or API dependencies (for example, for message-driven microservices that communicate over SNS/SQS). In particular, I have one domain value class that is a nested property on a top-level record class. If I want to use TableSchema.fromClass(RecordClass), then NestedClass also has to carry the @DynamoDbBean annotation, but then I have to add otherwise-unnecessary DynamoDB dependencies the client library (even if optional).

Proposed Solution

Add annotation @DynamoDbMixin(value = Class<?>) with target TYPE. Extend TableSchema.fromClass(Class) to also accept Class<?> mixins..., where if a type whose schema is being created has a provided mixin, the mixin is introspected to determine the properties to be mapped. The mixin should be checked only for property enumeration and should not require the presence of setters.

Other Information

No response

Acknowledgements

AWS Java SDK version used

2.21.25

JDK version used

openjdk version "11.0.11" 2021-04-20

Operating System and version

Gentoo Linux

debora-ito commented 1 month ago

but then I have to add otherwise-unnecessary DynamoDB dependencies the client library (even if optional).

I don't quite get this. Can you give more details?

Maybe show a code example with the solution you have in mind.

chrylis commented 1 month ago

Example:

package example.thirdparty.library

class Data {
  String id
  Integer quantity
  Subdata subdata

  static class Subdata {
    String description
  }
}
package my.application

@DynamoDbMixin(example.thirdparty.library.Data.class) // "apply these annotations as if they were present on Data"
@DynamoDbBean
interface DataMixin {
  @DynamoDbPartitionKey String getId()
  @DynamoDbFlatten Subdata getSubdata()
}

@DynamoDbMixin(example.thirdparty.library.Subdata.class)
@DynamoDbBean
interface SubdataMixin {}
TableSchema<Data> schema = TableSchema.fromClass(Data.class, DataMixin.class, SubdataMixin.class)

Inspired by Jackson mixins: https://github.com/FasterXML/jackson-docs/wiki/JacksonMixInAnnotations