Metadata(person extension)
平台提供有限的 metadata:讓你的應用把自己的少量結構化資料掛在一個人員身上,用平台的授權與租戶隔離保護它。
這不是你的資料庫。 你的業務資料、流程與歷史留在你自己的系統。這裡只放「必須跟著平台的人跑」的少量欄位。
定址
(租戶, person, extension)
- 租戶由 token 決定,不由參數決定。
personId是平台給的 TypeID(psn_…)。不可自行拼裝或解析,只使用平台給過你的值。extensionId是登記時由平台配發的 id。不要拿會改名的功能名稱當身分。未登記、或不屬於呼叫端 → 404(不是 403,避免洩漏 extension 是否存在)。
一個租戶可以有多個 extension;每個 extension 只有它的 owner 應用看得到。同租戶另一支應用寫的 extension 不會出現在你的列表裡,也不計入你的 total。
Revision 與前置條件
每筆資料有一個 revision,對外化成 ETag。
每個 PUT 必須恰好帶一個前置條件標頭,用的是 RFC 9110 的標準語意,沒有自訂延伸:
- 建立用
If-None-Match: *— 「只有在它還不存在時才寫」 - 更新用
If-Match: "<etag>"— 「只有在它還是這一版時才寫」
If-Match 不接受 *(那是 DELETE 才有的用法)。兩個都不帶、或兩個都帶,一律
428 precondition_required——本 API 沒有「無條件覆寫」這個操作,因為那正是遺失
更新的來源。428 是 client 的 bug,不是衝突;同樣的請求重試永遠同樣結果。
| 情境 | 送什麼 | 結果 |
|---|---|---|
| 建立新的一筆 | If-None-Match: * |
201 |
| 建立但它已經存在 | If-None-Match: * |
409 already_exists |
| 更新既有一筆 | If-Match: "<etag>" |
200 |
| 更新但版本已被別人改掉 | If-Match: "<舊 etag>" |
409 revision_conflict |
| 更新但那筆已被刪除 | If-Match: "<etag>" |
404 |
| 兩個都沒帶,或兩個都帶 | — | 428 precondition_required |
DELETE 必填 If-Match:"<etag>" 只刪那一版,* 不論版本都刪,省略 → 428。
已經不存在 → 204(冪等)。DELETE 不看 If-None-Match。
所有衝突都是 409,本 API 不用 412。 client 的錯誤處理只要分辨 Problem.error:
already_exists(你要建立但它已經在了)或 revision_conflict(你要更新但版本變了)。
兩者都沒有寫入任何東西。正確處理:重新 GET、合併、帶新的 ETag 重送。
PUT 是整筆取代,不是 patch:data 就是新的完整內容。
限制
| 限制 | 值 | 超過時 |
|---|---|---|
| 單筆 data 大小 | 16 KiB | 413 |
| 每 tenant 每 extension 筆數 | 50,000 | 422 quota_exceeded |
| 每 tenant extension 數 | 20 | 422 quota_exceeded |
| 分頁每頁筆數 | 預設 20,上限 100 | 422 |
額度判定與寫入在同一交易內完成,所以大量並行寫入不會衝破上限。
額度滿或方案降級不會刪任何既有資料。 寫入被拒(422),但讀取、刪除與匯出照常可用——你永遠有把資料拿走或減量的途徑。
不能放什麼
- 照片、檔案、逐題事件、任何無界成長的列表。
- 任何被當成 permission、餘額、購買權益或身份綁定的欄位。平台不會因為 metadata 說了什麼而授予任何權限。 你自己也不應該。
- 個資請按最小必要原則;平台的 person 主檔本身只回
personId、displayName、createdAt,metadata 不是拿來繞過這個界線的地方。
查詢
v1 只有兩種讀法:
- key lookup:
GET /v1/persons/{personId}/extensions/{extensionId} - 依 person 的有界分頁:
GET /v1/persons/{personId}/extensions
沒有任意 JSON path 查詢、沒有全庫掃描、不會自動索引你的欄位。要用自己的條件搜尋,請在你自己的資料庫做。
匯出與刪除
- 逐筆
GET就是匯出途徑;分頁有界,所以匯出是可預期的成本。 DELETE冪等,釋放筆數額度,但不會保留任何歷史。要保留請先匯出。- 租戶退出、person 合併或刪除之後的一致性由平台的 owning service 契約決定;這些情況下你的 extension 可能連帶消失。要長期保存的東西請放你自己的系統。