Summary
バックエンドの API パラメータ検証・レスポンス型定義・OpenAPI (api.json) 生成に使われているスキーマ基盤を、AJV + 独自拡張 json-schema (optional / nullable / ref / selfRef + SchemaType<> 型変換) から Valibot に移行する。
現行の仕組みは 1 つの as const スキーマオブジェクトが TS 型導出 / AJV 検証 / OpenAPI 生成 / misskey-js 型生成 の 4 役を担う設計で強力だが、独自拡張と型レベル変換 (SchemaType<>) の複雑さが保守・開発体験のボトルネックになっている。Valibot なら「スキーマ = バリデータ = 型 = spec」をValibotの標準機能だけで実現でき、独自基盤を撤去できる。
Purpose
解決したい問題
型パズルの保守コスト : SchemaType<> は excessive stack depth (Excessive stack depth comparing types 'SchemaTypeDef<?>' and 'SchemaTypeDef<?>' #8535 ) 回避のための UnionToIntersection 等を含み、スキーマを深くすると型推論が壊れる可能性がある
独自拡張の学習コスト : optional / nullable / ref / selfRef は JSON Schema 標準に無い独自仕様で、AJV からは未知キーワードとして無視される (paramDef と res で意味が変わる暗黙の規約もある)。新規コントリビュータの参入障壁にもなりうる
型と実態の乖離が隠れる : { type: 'object' } (properties 無し) 等が TS 上 any に潰れ、スキーマと実装の乖離がコンパイルでも実行時でも検出されない
エラー情報の貧弱さ : 検証失敗時は先頭 1 件の schemaPath (#/properties/x/type 形式) しか返らず、クライアントがどのパラメータの問題か特定しにくい (APIのrequired paramがanyOfな際のreasonメッセージの改善 #10928 )
移行で得られる利点
型チェックの高速化 : SchemaType<> の再帰条件型が消え、backend の typecheck の時間短縮が見込める (instantiations は増えるが再帰が浅くなる)
DX(Developer Experience) の改善 :
as const や型注釈のボイラープレートが不要になり、v.InferOutput で型が直接得られる
entity 参照が ref から直接 import になり、定義ジャンプ・補完・リネームが機能する
入出力型の分離: v.optional(x, default) で「クライアントが送る型 (省略可)」と「ハンドラが受け取る型 (default 適用済み)」が自動で分かれる
v.variant による判別 union、.entries spread による合成など、標準機能でスキーマを構成できる
検証エラーの改善 : dot-path (poll.choices.1 形式) + 全エラーの詳細を返せる (APIのrequired paramがanyOfな際のreasonメッセージの改善 #10928 , エラーメッセージのUIを良い感じにしたい #6322 )
隠れていたバグの顕在化 : any に潰れていた型の陰に隠れていたスキーマと実装の乖離・戻り型が違う箇所を検出可能。res スキーマが実行可能なバリデータになるため、将来的に開発環境でのレスポンス検証 (スキーマドリフト検出) も可能になる
spec の正確化 : エラーレスポンスの実 HTTP ステータスコード反映 (404 等)、「required と宣言しながら実際は省略可」だったパラメータの是正など、OpenAPI spec を実態に一致させられる
コード削減と依存整理 : スキーマ関連コードの削減や、valibot(軽量・モジュラーで tree-shaking 前提の設計)への移行でバックエンドのコード量を削減することが可能(なはず)
注意点
Do you want to implement this feature yourself?
Summary
バックエンドの API パラメータ検証・レスポンス型定義・OpenAPI (api.json) 生成に使われているスキーマ基盤を、AJV + 独自拡張 json-schema (
optional/nullable/ref/selfRef+SchemaType<>型変換) から Valibot に移行する。現行の仕組みは 1 つの
as constスキーマオブジェクトが TS 型導出 / AJV 検証 / OpenAPI 生成 / misskey-js 型生成 の 4 役を担う設計で強力だが、独自拡張と型レベル変換 (SchemaType<>) の複雑さが保守・開発体験のボトルネックになっている。Valibot なら「スキーマ = バリデータ = 型 = spec」をValibotの標準機能だけで実現でき、独自基盤を撤去できる。Purpose
解決したい問題
SchemaType<>は excessive stack depth (Excessive stack depth comparing types 'SchemaTypeDef<?>' and 'SchemaTypeDef<?>' #8535) 回避のためのUnionToIntersection等を含み、スキーマを深くすると型推論が壊れる可能性があるoptional/nullable/ref/selfRefは JSON Schema 標準に無い独自仕様で、AJV からは未知キーワードとして無視される (paramDef と res で意味が変わる暗黙の規約もある)。新規コントリビュータの参入障壁にもなりうる{ type: 'object' }(properties 無し) 等が TS 上anyに潰れ、スキーマと実装の乖離がコンパイルでも実行時でも検出されないschemaPath(#/properties/x/type形式) しか返らず、クライアントがどのパラメータの問題か特定しにくい (APIのrequired paramがanyOfな際のreasonメッセージの改善 #10928)移行で得られる利点
SchemaType<>の再帰条件型が消え、backend の typecheck の時間短縮が見込める (instantiations は増えるが再帰が浅くなる)as constや型注釈のボイラープレートが不要になり、v.InferOutputで型が直接得られるv.optional(x, default)で「クライアントが送る型 (省略可)」と「ハンドラが受け取る型 (default 適用済み)」が自動で分かれるv.variantによる判別 union、.entriesspread による合成など、標準機能でスキーマを構成できるpoll.choices.1形式) + 全エラーの詳細を返せる (APIのrequired paramがanyOfな際のreasonメッセージの改善 #10928, エラーメッセージのUIを良い感じにしたい #6322)anyに潰れていた型の陰に隠れていたスキーマと実装の乖離・戻り型が違う箇所を検出可能。res スキーマが実行可能なバリデータになるため、将来的に開発環境でのレスポンス検証 (スキーマドリフト検出) も可能になる注意点
v.objectは未知キーを出力から除去する (AJV は素通し)。宣言外キーに依存するハンドラが無いことは移行時に全数確認が必要minLength/maxLengthは Unicode コードポイント数、Valibot 標準は UTF-16 単位のため、公式に実装されるまではコードポイント数でカウントするカスタムアクションが必要 → maxCodePoints / minCodePoints (UTF-32 code points) open-circle/valibot#875anyOfの検証が AJV の部分検証より厳密になるケースがあるDo you want to implement this feature yourself?