microsoft / microsoft/typespec

Default encoding behavior creates a conflict

Open
#5,554 1 comment 0 reactions 0 assignees View on GitHub
compiler:core design:needed triaged:core
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.