対象読者
この記事は、次のような人を対象にしています。
静的LPや小規模サイトのフォームを実装している人
Astro、Hono、Cloudflare Workers などで軽量なフォームAPIを作りたい人
Zod、Valibot、Ajv、Pydantic などのスキーマバリデーションに関心がある人
AIコード生成を使いながら、フォーム仕様のズレを減らしたい人
複数のランディングページや問い合わせフォームを保守している人
Node.js だけでなく、Python、Go、Rust なども視野に入れて入力仕様を管理したい人
一方で、この記事では次の内容には深く踏み込みません。
React Hook Form や Formik の詳細な使い方
管理画面付きフォームビルダーの実装
複雑な業務アプリの権限制御
JSON Schema のすべてのキーワード解説
Go や Rust の具体的な validator 実装
この記事の目的は、実装手順の解説ではなく、フォーム仕様管理の戦略と行動方針を整理することです。
AI時代のフォーム仕様管理を「良い戦略、悪い戦略」で考える
AI に頼めば、問い合わせフォームの HTML や API のコードはすぐに生成できます。
しかし、フォーム開発で本当に面倒なのは「HTMLを書くこと」だけではありません。
たとえば、次のようなズレが起きます。
HTML では maxlength="80"
Valibot では maxLength(100)
API では 255 文字まで許可
メール本文では fullName として扱う
ログでは name として保存する
コードは生成できても、フォーム仕様の正本がどこにあるのかが曖昧なままだと、HTML、JavaScript、API、メール本文、ログ、ドキュメントが少しずつズレていきます。
そこで出てくるのが、フォーム構成やバリデーションルールを JSON / YAML のようなデータ形式で管理する考え方です。
ただし、ここで注意したいのは、JSON化すればすべて解決するわけではないということです。
この記事では、リチャード・ルメルトの『良い戦略、悪い戦略』で紹介される「診断、基本方針、行動」の考え方を参考にしながら、AI時代のフォーム仕様管理について考えます。
1. AIでフォームは作れるが、仕様はズレる
問い合わせフォームや資料請求フォームは、一見すると単純です。
名前
メールアドレス
問い合わせ種別
問い合わせ内容
同意チェック
送信ボタン
しかし、実際の開発では、同じフォーム項目がいろいろな場所に登場します。
HTML の name 属性
label
placeholder
required
maxlength
クライアント側バリデーション
API側バリデーション
メール本文
管理画面
ログ
テストケース
AI に「問い合わせフォームを作ってください」と頼めば、それらしい HTML や JavaScript は生成されます。
しかし、AI は毎回まったく同じ判断をするとは限りません。
name なのか fullName なのか
subject なのか inquiryType なのか
agree なのか privacyConsent なのか
maxLength は 80 なのか 100 なのか
この揺れを放置すると、フォームは動いているように見えても、仕様としては不安定になります。
つまり、AI時代のフォーム開発で重要なのは、コードを速く書くことだけではありません。
フォーム仕様の正本をどこに置くかが重要になります。
悪い戦略:JSON化すれば全部解決する、ではない
ルメルトの『良い戦略、悪い戦略』では、良い戦略には「診断、基本方針、行動」があると説明されます。
逆に、悪い戦略では、問題を診断せずに、スローガンや願望だけが並びます。
フォーム開発で言えば、次のような発想は危険です。
AIでフォームを自動生成すればよい
JSONでフォームを管理すればよい
OpenAPIのように全部自動生成すればよい
スキーマを書けばUIもAPIも安全になる
これらは、方向性として完全に間違っているわけではありません。
しかし、それだけでは戦略ではありません。
なぜなら、次の問いに答えていないからです。
何がズレて困っているのか
どの仕様を JSON に置くのか
どこから先はコードに残すのか
どこまで自動生成を目指すのか
AIにどこまで任せるのか
Node.js、Python、Go、Rust で同じ考え方が通用するのか
JSON化は行動のひとつです。
しかし、JSON化そのものは戦略ではありません。
悪い戦略は、いきなり道具から入ります。
Zodを使おう
Valibotを使おう
JSON Schemaにしよう
OpenAPI化しよう
良い戦略は、まず問題を診断します。
何が分散しているのか
どこでズレているのか
何を正本にすべきなのか
どこまで機械化し、どこから人間が判断するのか
フォーム仕様管理でも、この順番が重要です。
診断:本当の課題はフォーム仕様の分散である
フォーム開発の問題は、HTMLを書くことそのものではありません。
本当の課題は、フォーム仕様が複数の場所に分散することです。
たとえば、問い合わせフォームでは、同じ「メールアドレス」という項目が次の場所に現れます。
HTML:
<input type="email" name="email">
JavaScript:
email が空かどうかを確認する
API:
email が必須かどうかを検証する
メール本文:
返信先として表示する
ログ:
email として保存する
テスト:
不正なメールアドレスでエラーになるか確認する
これらがすべて手書きされていると、変更時にズレます。
たとえば、仕様変更で「問い合わせ内容は2000文字まで」と決めたとします。
しかし、実装が次のようになっていたらどうでしょうか。
HTML:
maxlength="2000"
クライアント側バリデーション:
maxLength(1000)
API側バリデーション:
maxLength(5000)
メール本文:
文字数制限を考慮していない
テスト:
2001文字のケースがない
この状態では、フォーム仕様が管理されているとは言えません。
つまり、診断はこうです。
問題は、フォームのHTMLを作ることではない。
問題は、フォーム仕様の正本がなく、HTML、JS、API、メール本文、テストに分散してズレることである。
この診断がないまま JSON 化しても、単に設定ファイルが増えるだけです。
基本方針:JSONを仕様の管理データとして使う
診断ができたら、次は基本方針です。
この記事での基本方針は、次のようになります。
フォーム仕様の正本を HTML ではなく、JSON / YAML のようなデータとして管理する。
ただし、最初から完全自動生成を目指すのではなく、
人間とAIが共有できる仕様データとして使う。
ここで重要なのは、完全自動生成を最初の目標にしないことです。
OpenAPI のように、仕様からクライアント、サーバー、ドキュメント、モック、テストまで全部生成したくなるかもしれません。
しかし、フォームの場合は API 契約だけでなく、UI、文言、確認画面、アクセシビリティ、メール本文、スパム対策まで関係します。
すべてを JSON で表現しようとすると、JSON が小さなプログラミング言語のようになってしまいます。
そのため、まずは次のように割り切るほうが現実的です。
JSON / YAML:
フォーム仕様の管理データ
AI:
仕様と実装の間を埋める補助
人間:
採用判断とレビュー
テスト:
仕様との一致確認
小さな自動化:
繰り返しが多い部分だけ生成
たとえば、フォーム定義には次のような情報を置きます。
{
"name": "email",
"label": "メールアドレス",
"control": "email",
"required": true,
"rules": {
"trim": true,
"maxLength": 254
},
"messages": {
"required": "メールアドレスを入力してください",
"email": "メールアドレスの形式で入力してください"
},
"description": "問い合わせ返信用のメールアドレス",
"rationale": "返信に必須のため、必須項目として扱う"
}
ここで description や rationale を持たせているのが重要です。
JSON は標準ではコメントを書けません。
そのため、AI や人間に伝えたい意図は、コメントではなくデータとして持たせる必要があります。
description:
その項目が何か
rationale:
なぜその項目や制約が必要なのか
AI時代には、コメントや設計意図は単なる補足ではありません。
AIへの制約条件であり、人間のレビュー基準になります。
フロントエンド、Node.js、Python、Go、Rustで見える世界は違う
JSON によるスキーマ管理は、対象範囲によって意味が変わります。
フロントエンドだけで使う場合と、複数のサーバーサイド言語まで広げる場合では、見える世界がかなり違います。
| 対象範囲 | JSONスキーマ管理の見え方 |
|---|---|
| フロントエンドだけ | フォーム構成、HTML属性、UX検証に使いやすい |
| Node.js / TypeScript | Valibot、Zod、Ajv と接続しやすい |
| Python | Pydantic-first か JSON Schema-first かを決める必要がある |
| Go | JSON Schema 検証と struct 変換を分けて考える必要がある |
| Rust | serde の型と JSON Schema の入力契約を分けて考える必要がある |
| 複数言語 | JSON Schema は共通の入力契約になりうるが、UIや業務ルールは別管理が必要 |
TypeScript だけで完結するなら、Valibot や Zod を中心に考えやすいです。
form.json
↓
Valibot schema
↓
クライアント側検証
↓
Hono API 側検証
一方、Python では Pydantic のように、Python のモデルから JSON Schema を生成する方向が自然な場合があります。
Pydantic model
↓
JSON Schema
これは Python-first の設計です。
逆に、JSON / YAML を正本にして Python でも使いたいなら、フォーム定義から Pydantic model へ変換する層が必要になります。
Go や Rust では、さらに注意が必要です。
Go や Rust の struct は、アプリケーション内部の型です。
一方で、JSON Schema は HTTP リクエストとして受け入れてよい JSON の形を表す入力契約です。
この2つを完全に同一視すると、次のような問題が起きます。
required と optional の違い
null と空文字の違い
未知フィールドを許すかどうか
integer の範囲
format: email の扱い
pattern の正規表現互換性
そのため、Go や Rust では次のように分けて考えるほうが安全です。
JSON Schema:
HTTPリクエストの入力契約
Go / Rust の struct:
アプリケーション内部の型
コード側の追加検証:
業務ルール、DB照合、セキュリティ判断
ここからわかるのは、JSON によるスキーマ管理は有効だが、すべてを同じように扱えるわけではない、ということです。
フロントエンドでは、フォーム構成データとして扱いやすい。
Node.jsでは、実行時バリデーションと接続しやすい。
Pythonでは、Pydantic-first か JSON Schema-first かを選ぶ必要がある。
Go / Rustでは、入力契約と内部型を分ける必要がある。
つまり、JSON は共通語にはなります。
しかし、各言語の型システムやバリデーション文化を無視できるわけではありません。
まとめ:完全自動生成ではなく、仕様駆動の半自動開発へ
ここまでの話を、ルメルトの「診断、基本方針、行動」で整理します。
| フレーム | フォーム仕様管理での意味 |
|---|---|
| 診断 | 問題はコード生成速度ではなく、フォーム仕様が HTML、JS、API、メール本文、テストに分散してズレること |
| 基本方針 | JSON / YAML を完全自動生成の道具ではなく、仕様の管理データとして使う |
| 行動 | フォーム仕様を正本化し、AIへの制約条件、レビュー基準、テスト観点として使う |
大事なのは、JSONで何でも解決しようとしないことです。
JSONで管理しやすいものはあります。
field name
label
control
required
minLength
maxLength
enum
error message
description
rationale
一方で、JSONだけでは管理しにくいものもあります。
複雑な業務ルール
DB照合
権限判定
非同期検証
Turnstile / CAPTCHA
レート制限
メール配送処理
セキュリティ判断
複雑な表示条件
したがって、行動方針としては次のようになります。
フォーム仕様の正本を JSON / YAML に置く
name、label、control、required、rules、messages、description、rationale を管理する
HTML、バリデーション、API、メール本文はその仕様と照合する
AIには仕様データを渡して実装案を作らせる
繰り返しが多い部分だけ小さく自動化する
Go / Rust など他言語では、JSON Schema を入力契約として扱う
業務ルールやセキュリティ判断はコード側に残す
逆に、最初からやらないほうがよいこともあります。
完全なフォームビルダーを最初から作らない
JSONに複雑な業務ロジックを書かない
すべての言語に同じコードを自動生成しようとしない
JSON SchemaだけでUIとAPIとセキュリティを全部表現しようとしない
AI時代には、仕様と実装の関係も少し変わります。
従来は、仕様ファイルから実装を作るには、かなり厳密なコードジェネレーターが必要でした。
しかし今は、仕様データを AI に渡して、HTML、Valibot schema、API handler、テスト観点のたたき台を作らせることができます。
もちろん、AIに自由生成させるのは危険です。
悪い依頼はこうです。
問い合わせフォームを作ってください。
よい依頼はこうです。
以下の form.json を正本として、HTMLとAPI検証を作ってください。
フィールド名、required、maxLength、エラーメッセージは変更しないでください。
仕様にない項目は追加しないでください。
つまり、AI時代のスキーマは、コードジェネレーターの入力である前に、AIへの制約条件であり、人間のレビュー基準です。
JSONによるスキーマ管理は、完全自動生成の銀の弾丸ではありません。
しかし、フォーム仕様を人間、AI、複数言語の実装が共有するための管理データとしては、十分に妥当です。
重要なのは、次の3つを分けることです。
JSONに置くもの
コードに残すもの
AIに埋めてもらうもの
この分担を決めることが、AI時代のフォーム仕様管理における基本方針になります。