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

Support codec switching based on model traits #2558

Open
popematt opened this issue Mar 10, 2025 · 0 comments
Open

Support codec switching based on model traits #2558

popematt opened this issue Mar 10, 2025 · 0 comments

Comments

@popematt
Copy link

The main use case I have in mind is a service that uses a non-JSON codec (e.g. CBOR) for the httpPayload, but errors are serialized as JSON. (This is something that seems to be supported by JAX-RS right now.) I could write an entire protocol for this, but I don't think that's a scalable solution, and it doesn't necessarily solve the second use case.

A second use case is for APIs that (for legacy or compatibility reasons) need to tunnel data of one format into another format. For example, using standalone smithy shapes, one might define a shape that represents a row in a DynamoDB table, and one of the fields could be binary-encoded data. Here's a straw-man example:

structure PersonRow {
    id: Uuid

    created: Timestamp

    lastModified: Timestamp
    
    tags: StringList

    @codec(cbor) 
    details: PersonDetails    // <-- Actually gets serialized as a blob that contains a cbor-serialized PersonDetails.
}

Then:

PersonRow row = dynamoDBJasonCodec.deserializeShape(serialized, PersonRow.builder());
// The PersonDetails is automatically deserialized.
PersonDetails person = row.getDetails();

This use case is currently manageable right now using a two-step process if you model details as a Smithy blob. First, you deserialize the PersonRow, then you read the details field deserialize it with the appropriate Codec implementation. However, it would be a nice quality-of-life improvement if that can be done automatically, and this approach means that type safety of the details field is built in to the generated model(s) and the documentation shows the correct type (as opposed to the type being blob).

One possible solution involves adding a "delegating" or "composite" codec implementation, although that solves only part of the problem. I think that for this feature to be fully realized, all of the protocols would need to use the composite codec, specifying a default codec. Then, other codecs could be included in the composite codec, as desired (in Java, perhaps using Java SPI). ...so maybe this "composite codec" is actually a CodecManager rather than a Codec implementation.

There are also some open questions, for which I do not have an answer:

  • Would a codec trait indicate that particular codec is required, or would it be okay to fallback to the "default" codec?
  • Should the codec traits appear on fields? (I think "yes".) What about operations, error shapes, general shapes?
  • Should there be a single @codec trait that accepts a codec name, or should each codec have its own trait?
  • Should things that are embedded using different codecs be eagerly deserialized or lazily deserialized (i.e. the generated shape can hold a hidden blob that will be deserialized only if the field it backs is actually requested)?

I am willing to contribute towards the design and implementation of this feature.

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

No branches or pull requests

1 participant