microsoft / microsoft/typespec
Default encoding behavior creates a conflict
- Dominant language
- Java
- Stars
- 5.9k
- Forks
- 394
- Avg merge
- 1d 23h
- Merged PRs (30d)
- 104
Description
We prescribe some default encoding pairs for JSON, e.g. `["base64", string]` for bytes, `["rfc3339", string]` for DateTime-like scalars.
Additionally, we've said that emitters are meant to give encodings a treatment that goes something like:
> When an emitter encounters an encoding pair `[Encoding, Type]` for a given canonical type `Source`, emitters should resolve this by modeling `Source` _as if_ it were `Type` and emitting a warning advising that the emitter cannot handle the encoding and will instead require the client/server consumer/implementor to handle the wire type directly.
There are a couple of problems with this approach:
1. The **default** encoding of a type depends on the MIME type of serialization. A type may be subject to multiple different serializations in the same context. Consider:
```tsp
model Data {
created: utcDateTime;
}
op example(): {
@header contentType: "application/json" | "application/x-protobuf";
@body data: Data;
}
```
In this example, the output serialization format of the body should depend on the `Accept` header submitted by the client and/or the type chosen by the service implementation.
In JSON, `utcDateTime` has a default encoding pair `["rfc3339", string]`, but in Protobuf, `utcDateTime` has a built-in representation in Google's library. Supposing an emitter does not implement the `"rfc3339"` encoding for `utcDateTime`, how should it represent the type of `Data#created` in the response? The default treatment for JSON requires `created: `, but the treatment for `"application/x-protobuf"` would require `created: `
2. When emitters implement support for additional encodings, this will manifest as a **breaking change** in generated code. The type will quietly be replaced with an incompatible type when/if the emitter does _eventually_ support the unknown encoding (e.g. `created: string` may _eventually_ become `created: Date` or `created: Temporal.Instant`, and these types are nonoverlapping, leading to breaking changes in both input and output assignability of ``.
Contributor guide
Assessment
This issue has not been assessed yet.