フォームデータモデルの大いなる断絶

今回はユーザー入力データにアクセスするための API、あるいはフォームデータモデルについて書きたいと思います。Schema-Woven Validation は異なるプラットフォームでも一貫したバリデーションロジックを提供する枠組みですからバリデーションの対象であるフォームデータの一貫性が基礎となりますが、各プラットフォームが標準装備するフォームデータモデルにはびっくりするぐらいの違いがあるのが現実です。

クライアント側のフォームデータモデルの代表格である JavaScript の FormData インターフェイスと、サーバー側でよく使われる PHP のスーパーグローバル変数の比較を見てみましょう。

たとえば次のようなユーザー入力があったとします。

country=China

FormData ではフィールド名と入力値のペアの配列として以下のように表現します。

JSON
{
[
[ "country", "China" ]
]
}

PHP ($_POST) の場合は連想配列として扱われるので以下のようになります。

JSON
{
"country": "China"
}

同じ名前のフィールドが2つあるケースを見てみましょう。

country=China&country=India

FormData では以下のようになります。

JSON
{
[
[ "country", "China" ],
[ "country", "India" ]
]
}

PHP の場合は連想配列の性質から以下のように最後のフィールド値がそれより前のものを上書きします。

JSON
{
"country": "India"
}

さらに角括弧 ([]) つきのフィールド名を使ったケースでは両者の違いがより鮮明になります。

country[]=China&country[]=India

FormData は角括弧をフィールド名を構成する意味を持たないただの文字として扱うので以下のような構造になります。

JSON
{
[
[ "country[]", "China" ],
[ "country[]", "India" ]
]
}

一方 PHP では角括弧は配列リテラルの意味を持つため、データの構造は以下のようになります。

JSON
{
"country": [ "China", "India" ]
}

というわけで一般的な文字列のユーザー入力でもざっとこのような大きな違いが見られます。これにさらにアップロードファイルの扱いがどうなるか詳しく見ていくと、あまりの違いの大きさと複雑さに発狂せずにいることが難しく思えてきます。

このようなバラバラのフォームデータモデルの上に一貫性のあるバリデーションロジックを構築するのは無理があるので、SWV では FormDataTree というインターフェイスを挟んでそこでプラットフォーム間の差異を吸収しているのです。


Comments

Leave a comment