結構與內建 (Schemas)
@oneOf
extern dec oneOf(target: Union);標註在 union 上,輸出 oneOf(恰好一個 variant 成立)取代預設的 anyOf(至少一個成立)。在 schema 轉換層生效:
@oneOf
union Shape {
circle: Circle,
square: Square,
}Shape:
oneOf:
- $ref: "#/components/schemas/Circle"
- $ref: "#/components/schemas/Square"@jsonSchemaExtension
extern dec jsonSchemaExtension(target: Model | ModelProperty, key: valueof string, value: valueof unknown);在目標的輸出 schema 加一組原始 key/value。這是沒有專屬 decorator 時的逃生口。可重複套用,每次加一組。extension key 會蓋過 emitter 自己產生的同名關鍵字。
@jsonSchemaExtension("unevaluatedProperties", false)
model Strict {
id: string;
}Strict:
type: object
properties:
id:
type: string
required:
- id
unevaluatedProperties: falseschema key 怎麼決定
被 message 觸及的每個具名 model、enum 與 union,都在 components.schemas 得到一筆項目。key 依這個順序決定:
- 有
@friendlyName時,解析後的文字直接是整個 key。不加 namespace 前綴。 - 沒有時,key 是宣告名稱,前面加上 namespace 鏈。各段用
.連接。例如namespace Contracts.TransactionHistory裡的model WithdrawCompleted,key 是Contracts.TransactionHistory.WithdrawCompleted。
service namespace 與 compiler 內建的 TypeSpec namespace 會從鏈中剔除。單一 service 的 spec 裡幾乎每個宣告都住在 service namespace 底下,這一段沒有區別資訊。@typespec/openapi3 也是同樣剔除。
住在 service namespace 之外的 library namespace 的宣告,會保留那段 namespace 當前綴。要縮短這種 key,套 @friendlyName。
components.messages 的 key 遵循同一套規則,只有兩個差異。message key 一律不帶 namespace 前綴。而 @message 的引數覆寫 message key,作用等同 @friendlyName 覆寫 schema key。
key 的字元清理
Components Object 的 key 必須符合 ^[a-zA-Z0-9.\-_]+$。AsyncAPI 不允許成員名稱帶其他字元。
一般的 TypeSpec 識別字本來就落在這個字元集內。它原樣成為 key,大小寫不變。@friendlyName 的文字與反引號括起的名稱可以帶其他字元,emitter 會改寫這些字元:
.、-、_原樣保留。- 每個英數字片段的第一個字母改成大寫。
- 其他字元一律改寫成
Sep加上該字元的 code point。例如has space變成HasSep32Space。
schema key 被改寫時不回報。message key 被改寫時回報 sanitized-message-key。讓每個 @friendlyName 與 @message 引數都落在字元集內,改寫就不會發生。
emitter 會讀的內建 decorator
以下來自 @typespec/compiler,不需要 import:
| Decorator | 在本 emitter 的效果 |
|---|---|
@service(#{ title }) | 標記 service namespace。title → info.title。一份文件一個 service。第二個會警告(multiple-services)並忽略。 |
@tag("name") | 每次套用產生一筆 info.tags。它標不到 Model,message 的 tag 改用 @asyncTag。兩者指到同一個名字時會合併。 |
@doc / 文件註解 | description。在 namespace 上是 info.description 的後備。在 schema 層的宣告與屬性上也生效。 |
@summary | schema 的 title。 |
@example(#{...}) | schema examples 的一個項目,序列化為 JSON。 |
@discriminator("prop") | schema 的 discriminator。見繼承。 |
@encodedName("application/json", "wire_name") | 改寫 schema 的屬性 key。見 wire key。 |
@friendlyName("{name}X", T) | 覆寫宣告的 components.schemas key。 |
@minLength、@maxLength、@pattern、@format、@minValue、@maxValue、@minValueExclusive、@maxValueExclusive、@minItems、@maxItems | 驗證關鍵字。見對應表。 |
TIP
schema 層的 decorator(@oneOf、@jsonSchemaExtension 與形塑 schema 的內建 decorator)目前只在轉換層生效。見 Schema 轉換開頭的狀態說明。