http://coderepos.org/share/browser/events/phpframework/piece_framework/trunk
機能をすべて実装したものの、まだまだチューニングや見えざる敵(bug)との戦いが控えています。
俺たちの戦いはこれからだ!
r15761 号をもってコミットメントは終了です。
ご愛読ありがとうございました。
http://coderepos.org/share/browser/events/phpframework/piece_framework/trunk
機能をすべて実装したものの、まだまだチューニングや見えざる敵(bug)との戦いが控えています。
俺たちの戦いはこれからだ!
r15761 号をもってコミットメントは終了です。
ご愛読ありがとうございました。
Piece_ORM を使えば、だれでも簡単にデータベースを使ったPHPプログラムを書くことができます。(任天堂のCM風に。)
1. フォルダの作成
Piece_ORM を動作させるには、プログラムのファイルとは別に3つのフォルダを使います。
プログラムファイルを作成するフォルダ内に、次の3つのフォルダを作成します。
・config
・cache
・mappers
2. データベース情報を準備する
次に Piece_ORM から接続するデータベースサーバの情報を設定します。
仮にデータベースの情報が
データベース: PostgreSQL
ホスト名: localhost
database : example
username : example_user
password : example_password
以上のようなものなら、先ほど作ったフォルダのうちの1つ、config フォルダの中に「piece-orm-config.yaml」という名前のファイルを作成し、次のように記述します。
- name: database1 dsn: pgsql://example_user:example_password@localhost/example
3. テーブルを準備する
続いて、実際にプログラムから読み込みや書き込みを行おうとするテーブルを準備します。
データベース内の実際のテーブルは予め作成しておきます。ここでは「person」という名前のテーブルを作成したとします。
先ほど作ったフォルダのうちの1つ、mapper フォルダの中に「Person.yaml」という名前のファイルを作成します。中身は何も必要ありません。
4. プログラムを書く
最後にプログラムを書きます。書くプログラムは非常に短くて簡単です。
SELECT 文の SQL は次のようなコードを準備します。SELECT した結果のレコードがオブジェクトとして簡単に参照が可能です。
<?php
// Piece_ORM を読み込む
require_once 'Piece/ORM.php';
// Piece_ORM を設定する
Piece_ORM::configure('config', 'cache', 'mappers');
// person テーブルを対象にする
$mapper = Piece_ORM::getMapper('Person');
// select * from peron where id = 1;
$person1 = $mapper->findById(1);
echo $person1->name; // name カラムを表示
// select * from peron where name = 'foo';
$person2 = $mapper->findByName('foo');
echo $person2->name;
?>
INSERT, UPDATE, DELETE も簡単です。
<?php
// Piece_ORM を読み込みと設定
require_once 'Piece/ORM.php';
Piece_ORM::configure('config', 'cache', 'mappers');
// person テーブルを対象にする
$mapper = Piece_ORM::getMapper('Person');
// 新しいレコードとして INSERT
$person = new stdClass();
$person->name = 'foo';
$mapper->insert($person);
// name カラムを変更して UPDATE
$person->name = 'bar';
$mapper->update($person);
// DELETE
$mapper->delete($person);
?>
ページの中に準備された1つのフォームから、例えばいくつかの別ページへ遷移したり、何らかの処理を実施するため複数ボタンを準備するようなケースがあるかと思いますが、
<button type="submit" name="{__eventNameKey}_next" value="次へ" />次へ</button>
<button type="submit" name="{__eventNameKey}_back" value="戻る" />戻る</button>
なんでもないこのコード、IE では正常に動作しません。
具体的には、「戻る」ボタンを押したにも関わらず、「次へ」ボタンを押したように振舞ってしまいます。これは、フォームへの Submit が実行されると、準備された2つのボタンともにリクエストパラメータとしてPOSTされてしまうためです。ボタンには Piece Framework を制御するためのイベント名が付与されていますが、2つのイベントリクエストが飛んできてしまうため、実行すべきイベントが正しく認識できなくなってしまうのです。
ボタンによるイベントの切り替えを Form への Submit で行う場合は、<button> タグではなく <input type="submit"> で対応するようにしましょう。
<input type="submit" name="{__eventNameKey}_next" value="次へ" />
<input type="submit" name="{__eventNameKey}_back" value="戻る" />
上記のような入力フォームで氏名の姓・名ともに入力値の必須バリデーションを行う場合、それぞれのリクエスト毎に必須確認およびエラーメッセージを設定すると、片方のみ未入力というケースならばよいものの、
両方ともに未入力の場合だと、上のような感じに。
これを回避しようとすると、テンプレート側で「どっちもエラーならば片方のみ表示して~」というような分岐文を書いてしまうところです。
ここは、次のようなバリデーションを行うようにします。
- name: lastName
filter: &Japanese
- trim
- JapaneseH2Z
- name: firstName
filter: *Japanese
- name: name
required:
message: 未入力です
pseudo:
format: %s%s
arg:
- lastName
- firstName
これで、lastName, firstName のどちらかが未入力だった場合 name カラムもブランクとなり、required ルールにヒットしエラーとなります。あとはテンプレートにて name カラムについてのエラー処理を行えば OK です。もちろん、lastName, firstName の値もそのまま利用できます。
前のエントリでさらっと使用していたりするのですが、Piece_Right のバリデーションルールの1つである WithMethod において複数のリクエストカラムを使った処理を実施したい場合は、WithMethod で指定したメソッドの第3引数として渡される Piece_Right_Results オブジェクトを利用します。
function checkPassword($password, $context, $results)
{
// username リクエストの値を取得
$username = $results->getFieldValue('username');
....
}
なおここで受け取れる値は、既にバリデーション済みの対象に限ります。すなわち、このメソッドが実行される WithMethod バリデーションが行われる前に、あらかじめ username に対してのバリデーションが済んでいる必要があります。
バリデーションは、通常はバリデーションルールの書かれた yaml ファイル内の順に実行されますので username カラムを一番に記述しておけば問題はないはずです。確実に最終バリデーションとして実行したい場合は、validator とは別に記述することのできる finals を利用することで、すべてのバリデータ実行の後に改めてバリデーションを行うことができます。
- name: username
required:
message: ユーザ名を入力ください
filter: &AlphaNumeric
- trim
- JapaneseAlphaNumeric
validator:
- name: Length
rule:
min: 6
max: 255
- name: password
required:
message: パスワードを入力ください
filter: *AlphaNumeric
validator:
- name: Length
rule:
min: 6
max: 255
finals:
- name: WithMethod
rule:
class: AuthenticationAction
method: checkPassword
message: 認証に失敗しました
ちょうど先週のことですが、Piece_Unity 向けの認証用コンポーネントの1つである Piece_Unity_Component_Authentication の Stable 版がついにリリースされました。
今年7月に Piece_Unity と付随するコンポーネント群が Stable 版として一斉にリリースされていた中、唯一このコンポーネントのみが Beta 版のまま残り続けていた状態でした。実はこの数ヶ月間の間に Stable 版として実用に耐えうるよう議論、実装、試用を続けてきたのでした。
リリースノートにも記載しているとおり、この Stable 版は過去バージョンの内容と一切の互換性はありません。したがって過去のバージョンからの移行は設定ポイントの修正が必要となりますので注意してください。
そしてもう1つ注意点として、次に紹介する Stable 版の機能を確認してしまうと、居ても立っても居られずに Stable 版の仕様に修正したくなってしまうかもしれません。:)
Piece_Unity_Component_Authentication は、以下の2つのポイントがあります。
・インターセプタープラグイン
・クライアント向けインターフェース
ベータ版当時より存在していたインターセプタープラグインですが、設定ポイントの内容が変更になっています。
具体的には、設定ポイントの階層が1つ上にあがっています。
以前は「services」設定ポイント以下に認証対象を指定する「resources」や認証フローへのアドレス「url」などを連想配列で指定していましたが、servicesを排除し「resources」「url」といった設定ポイントへ繰り上がることになりました。
また後述するクライアント向けインターフェースの登場により、認証確認のためのクラス・メソッドが必要でなくなりました。
認証機構が含まれるサイトを構築する際における、普段の認証向け設定ポイントのエントリは以下のようにすっきりしたものになります。
この例では、「/members/」というパスが含まれるURLにアクセスした場合に認証是非の判定が行われ、認証済み状態ならばそのまま実行、非認証状態ならば「https://<任意のドメイン>/login.php」へ自動転送される動作となります。
- name: Interceptor_Authentication
point:
- name: resourcesMatch
type: configuration
value:
- "/members/.*"
- name: url
type: configuration
value: https://example.com/login.php
Piece_Unity 利用時における、認証に関する情報の保持・取得を行うためインターフェースとして、「Piece_Unity_Service_Authentication」という専用のクラスが新たに準備されました。
このクラスは、任意の Piece_Unity のフロー (例えば Authentication フロー) 内、つまりフローアクション内で利用します。
たとえばユーザに対して認証済みの状態にする場合、以下のように Service_Authentication の login() メソッドを実行します。
$authentication = &new Piece_Unity_Service_Authentication(); $authentication->login();
ログアウト時、すなわち非認証状態にする場合は、logout() メソッドを実行します。
$authentication = &new Piece_Unity_Service_Authentication(); $authentication->logout();
たったこれだけのコードで Interceptor_Authentication における認証是非の判定が得られます。
過去のバージョンを利用した認証機構サンプルコードでは、非認証状態時に元々アクセスしようとしていたURLへ認証後自動転送されるという処理コードを紹介していましたが、この機能も removeCallback() メソッド1つですべて実現できるようになりました。
恐らく認証後に転送されるという利用法になるでしょうから、以下のコードのように login() → removeCallback() と連続で実行するようにします。
$authentication = &new Piece_Unity_Service_Authentication(); $authentication->login(); $authentication->removeCallback();
最後に、簡易的な認証フローを実現するためのサンプルを軽く紹介しておきます。これだけで認証状態のON/OFF切り替えと、元URLへの自動転送が実現できます。以前のものと比べて「かなり」スマートな内容になっているかと思います。(以前のものはもう書かない。)
Authentication.yaml (フロー定義)
firstState: DisplayForm
viewState:
- name: DisplayForm
view: Form
transition:
- event: authenticate
nextState: ProcessAuthentication
- name: DisplayMenu
view: Menu
transition:
- event: logout
nextState: DisplayForm
action:
method: logout
actionState:
- name: ProcessAuthentication
activity:
method: authenticate
transition:
- event: goDisplayForm
nextState: DisplayForm
- event: goDisplayMenu
nextState: DisplayMenu
AuthenticationAction.php (フローアクション)
require_once 'Piece/Unity/Service/FlowAction.php';
require_once 'Piece/Unity/Service/Authentication.php';
class AuthenticationAction extends Piece_Unity_Service_FlowAction
{
function authenticate()
{
$this->_user = &new StdClass();
$validation = &$this->_context->getValidation();
if (!$validation->validate('Authentication', $this->_user)) {
return 'goDisplayForm';
}
$authentication = &new Piece_Unity_Service_Authentication();
$authentication->login();
$authentication->redirectToCallbackURL();
return 'goDisplayMenu';
}
function logout()
{
$authentication = &new Piece_Unity_Service_Authentication();
$authentication->logout();
}
function checkPassword($password, $context, $results)
{
$username = $results->getFieldValue('username');
if ( <$username, $password を使って認証是非を確認> ) {
return true;
} else {
return false;
}
}
}
Authentication.yaml (バリデーションファイル)
- name: username
required:
message: ユーザ名を入力ください
filter: &AlphaNumeric
- trim
- JapaneseAlphaNumeric
- name: password
required:
message: パスワードを入力ください
filter: *AlphaNumeric
validator:
- name: WithMethod
rule:
class: AuthenticationAction
method: checkPassword
message: 認証に失敗しました
第3弾の今回で最後になります。今回は、ステートフルWebアプリケーションで戻るボタンを利用するための方法、および戻るボタンの利用是非について紹介していきます。
(7) ステートフルWebアプリケーションで戻るボタンを機能させる
前述したとおり、ステートフルなWebアプリケーションではブラウザ機能の戻るボタンによる再描画に対しての振る舞いを簡単に抑制することが出来ます。通常は状態の遷移を行うための指示(以下イベント)を規定していく形でフローを構築するため、結果的に戻るボタンは機能しなくなります。
この戻るボタンを機能させるにはどうすればよいか。PCブラウザの場合、戻るボタンを押すと1つ前のサーバリクエストが発生します。このことより、通常の遷移と同じように戻るボタンを押すことで発生する遷移イベントを予め想定して設定しておけば良いのです。
図7. 3画面間を遷移するサービス

図7は、再び3画面を遷移するサービス例です。このサービスのステートフルモデルによる構築で、戻るボタンを有効化するための遷移イベントを追加すると、図8のようになります。
図8. 3画面間遷移サービスに戻るボタンを有効化

図中の赤矢印部分は、全く同じリクエスト内容であることを示しています。PageCが表示されている状態で戻るボタンが押されると、1つ前のリクエスト、つまりPageBが表示されるための「toB」が実施されます。PageCからPageBへ戻るためには、この「toB」イベントをPageC自身も受け取るよう準備しておけば、正しく戻るボタンによる状態遷移が出来るようになります。
なお、図8ではPageBからPageAへ戻るためのイベントが指定されていませんが、これはPageBで戻るボタンを押すことで実行されるリクエストが、このステートフルWebアプリケーションが開始されるためのリクエスト(ステートフルモデルから見ればイベント無しにあたる)で、厳密にはリスタートのような扱いとなりますので、PageBからPageAへは自然と戻っているように動作します。
ただし、全ての状態遷移について戻るボタンを有効にする必要はありません。図9の例を見てください。
図9. 会員登録アプリケーション例

図9は、良くあるサービス利用に伴う会員登録を行うためのアプリケーションフローの例です。説明文を表示した後、入力フォーム、確認画面、登録完了画面の4画面を遷移します。それぞれの遷移に伴う位置づけとして、登録開始(start)、入力項目の確認/妥当性チェック(validate)、情報確定と登録(register)です。この例において戻るボタンを有効化する場合は、以下の図10のようにすべきです。
図10. 会員登録フローに戻るボタンを有効化

先ほどと同じように、戻るボタンに伴う再リクエストで共通化している箇所は赤矢印になっています。ここでは、確認画面から入力フォームへの戻り(つまり再入力)にあたる逆遷移は戻るボタンの有効化で可能としているのに対し、完了画面から確認画面への逆遷移は設けていません。これは登録完了後戻るボタンにより逆遷移→確認画面から再び再登録 といった二重投稿を禁止するためです。「会員登録を行う」という目的のため動作させていたフローとして無事登録が終了した以上、画面を戻す必要はありません。もし仮に確認画面で見ていた入力情報をまた見せたいのであれば、この完了画面で再び表示すればよいでしょう。
なお、当然ながら「再読み込み」ボタンによる再リクエストの二重投稿も発生しません。これはステートフルモデル内で、完了ページが regisrer を受け取って何かしらの処理をするような設定を一切行っていないからです。完了ページを表示し最終遷移まで到達した今、このステートにおいてこれ以上の遷移およびそれに伴う処理が起きることは2度とありません。ステートレスなWebアプリケーションで良くある Token などによる二重投稿チェックなどは必要なく、ステートフルWebアプリケーションの利点の1つだと言えます。
このように戻るボタンを有効化するポイントは、そのアプリケーション毎においてケースバイケースで考える必要がありそうです。おおよそ、データベースへの挿入・変更処理が伴うポイントやメール送信といった、「一度だけ実施すればそれで十分」である処理に伴う状態遷移において考えることになるでしょうが、やはり現在のところベストプラクティスは出ていません。
(8) au 端末における戻るボタンの利用
過去2回にて紹介したとおり、au 端末における戻るボタンはPCおよび他の携帯端末とは異なり、ページキャッシュの再表示を行うよう動作します。
しかし au 端末は、戻るボタンそのものの動作(ボタンを押すとどうなるか)を制御することの出来る仕様をあわせて備えています。これは他の携帯端末にはない機能で、au EZWeb のコンテンツを構成する WML を記述することでこれを実現します。この事については以前あげたエントリの通りで、私も参加しているステートフルなWebアプリケーションフレームワーク Piece Framework の HOWTO にも記載されるようになりました。
Piece Frameworkを使ったEZWeb向けWebサイトの遷移制御
Piece_Unity HOWTO
EZweb端末の強制的なブラウザキャッシュに適切に対処する
前述した (7) のように、戻るボタンによって状態遷移イベントを発生させるよう振る舞う動作を au 端末向けにも実装するには、描写ページ内で WML を記述します。例えば図8の遷移を au 端末で実現させる場合、PageCの body コンテンツ内の末尾にリスト1のようなコードを埋め込みます。
リスト1. 図8の遷移を実現するための PageC HTML ソース (抜粋)
<wml:do type="prev">
<go href="「toB」イベントに該当するリクエスト" />
</wml:do>
また、図10の遷移を au 端末で動作させる場合、完了画面コンテンツ内ではリスト2のようなコードを埋め込むことで、戻るボタンを完全に機能しないようすることができます。
リスト2. 図10の完了画面を実現するための HTML ソース (抜粋)
これで au 端末向けにおいても、PC や他の携帯端末と同じ動作となるようになります。
このように挙動の異なる場合においても、ちょっとした+αのコードを追加する形でWebアプリケーションの仕様・挙動が共通となるよう構築するよう心がけるほうが、結果的に開発者およびサポート担当者の負担は軽くなり、最終的には還元される形でユーザにも使いやすいアプリケーションとなっていくのではないでしょうか。
前回のエントリの第2弾で、続きのお話になります。
今回はステートフルWebアプリケーションとしてシステム構築を行った場合、その基本的な動作のお話(おさらい)、戻るボタンに伴う動作、そして携帯端末におけるシステム利用と戻るボタンによる動作の違いについて、図による解説を含めて紹介します。
(4) ステートフルWebアプリケーションの基本動作
例えば以下の図1のようなサービスがあったとしましょう。
図1. 3画面間を遷移するサービス

PageA, PageB, PageC という3画面があり、PageAからPageB、そしてPageBからPageCという画面遷移を行うサービスであるとします。
ステートフルなシステムとして構築する場合は、PageAをスタート地点として、PageAからPageBへ行きたいという「toB」指示が出るとPageBへ遷移、同じくPageBにいる状態で「toC」指示が出るとPageCへ遷移するという意味になります。ステートフルですので、必ずPageAから始まることを限定しています。またPageAにいる状態で「toC」と言われても遷移することもありません。
このサービスを実際に実行した例が図2になります。
図2. 3画面遷移を実行した例

緑色のマークはこのサービスを利用するユーザ(クライアント)です。PageAから始まり、「toB」指示と共にPageB、その後「toC」指示と共にPageCへ遷移していることを示しています。PageA〜PageCまでを閲覧しているページ、緑色マークは現在閲覧中の場所の目印、黄色のふきだしはGET/POSTリクエストで、赤矢印はそれに伴う画面描写の切り替え(リフレッシュ)と観るとさらに分かりやすいかもしれません。
(5) 戻るボタン使用による状態の非遷移
上記図1の3画面遷移サービスに対しブラウザの「戻る」ボタンを使用するとどうなるでしょうか。
前述したように、あるページを表示している状態において想定していない遷移指示が出たとしても勝手に遷移するようなことはありません。通常は「意味のない指示」と判断し、その場の状態に留まろうとします。(ステートフルなWebアプリケーションを実現するためのライブラリおよびフレームワークの仕様に基づきます。)
例えば PageC まで遷移済みの状態から戻るボタンを押下した場合、ユーザは PageC の1つ前のページ、つまり PageB に戻ると想像することでしょうが、図3のように画面リフレッシュが行われたにも関わらずPageCが再描画されるという動きになります。
図3. 戻るボタンを押しても現ページが再描画される

(6) 携帯キャリア毎における戻るボタン押下と画面〜システム状態の認識ずれ
さて、この3画面遷移サービスを携帯端末で利用するとします。キャリア毎に携帯端末の仕様がありますが、基本的なWebアクセスのための通信機構はPCのものと何ら変わらない仕組みになっているため、PCと変わらないサービス内容を利用することができます。これは、戻るボタンに関する事柄も全く同じです。
前回にも紹介しましたが、Docomo, Softbank 端末の場合戻るボタンを押下すると1つ前に行ったサーバリクエストを改めて実施します。これはPCと同じ仕様のため、図3と全く同じ動きになります。
PCによる画面表示の情報量に比べ携帯端末は若干少ないため、「あれ、ひょっとすると画面が戻っていない?」と認識するまでに時間を要する可能性があるかもしれません。今まで当たり前のように利用していた戻るボタンがまさか効かないと考えることが出来ず、行動に対する応答内容のズレに混乱をきたす利用者も出るかもしれません。
au の場合はさらに悲惨なことになっています。前回のエントリの通り、auの戻るボタンはページキャッシュの再表示です。容赦なく前回ページをそのまま再表示しますので、図4のように完全に画面〜システム間の状態相違が発生します。
図4. auにおける画面〜システム間の状態相違

ユーザは戻るボタンでPageBに戻っているつもりですが、システムでは PageC にいることになっています。仮にこの遷移サービスが図5であったとしましょう。PageB からは PageC だけでなく、「toD」指示で PageD へ行ける遷移になっているとします。このようなサービスにおいて、au 端末で戻るボタンを駆使して画面遷移を行おうとすると、図6 のようになってしまいます。
図5. 画面間遷移するサービス その2

図6. ユーザにとって思いがけない画面遷移

PageC から戻るボタンで PageB に戻り、PageD へ行こうとします。画面上では PageB に戻ったことになっていますし、PageD へ遷移するための「toD」に相当するようなページリンクもあるでしょう。しかしPageB は「戻ったつもり」の扱いとなっており、PageD へ行こうとしても実際は PageC にいるわけですから、「PageC を再描画する」という動きとなります。ユーザにとっては「どうして!?」という動きに違いないでしょう。
このように、携帯キャリア毎にシステムそのものの挙動が異なることになっています。これらは統一した挙動となるよう、調整をかける必要があるでしょう。
またこれとは別に、戻るボタンそのものについてその取り扱いを考える必要があるでしょう。システムとして不具合が発生せぬよう制限を設けることは重要ですが、だからといってユーザビリティを損なうようなサービスにしてしまってはいけないということです。ということでもう少しだけ続きます。
以前 Piece Framework で作る EZWeb 向けサイトの画面遷移のお話をあげましたがその結果「極めて一部な人達にのみ好評」だったため、その補足および、より詳細な情報・アプローチを含めたお話です。久々に技術的なお話をあげたと思えばこういう極めてニッチな事柄であるのが hatotech::kumatch です。
なお既にタイトルに 1 とつけているだけあって、少しだけ連続したエントリになります。
(1) 挙動の異なる「戻る」ボタン
現在日本国内では複数のキャリアがそれぞれの携帯端末仕様を展開し、それらに準ずる端末が発売されています。
ご存知のとおり各携帯端末にはWebサイトを閲覧する機能が備わっており、各キャリア向けの仕様に基づくサイトを閲覧できる専用のブラウザが組み込まれています。
携帯端末ブラウザはPCで利用するようなブラウザと同じようにページコンテンツを表示したり「ブックマーク」「再読込み」といった機能が準備されていますが、そのうちの前画面に戻るために利用される「戻る」ボタンの挙動がキャリアによって異なることになっています。以下にそのパターンを紹介します。
なお、今回の話に Willcom や eMobile の端末は含めないものとします。現在のところこの2キャリアについては携帯キャリア端末としての動作とは異なり PC となんら変わらず振舞うことができると考えることができるからです。
● 再リクエスト形式
Docomo、Softbank の2キャリアは「戻る」ボタンを押下すると、1つ前に行ったサーバへのリクエストそのものを改めて行います。このとき画面に表示される内容はこのリクエストに伴う結果によるもので、これは PC におけるブラウザ仕様と同じであると言えます。
● ページキャッシュ形式
au の端末で「戻る」ボタンを押下した場合、1つ前の画面で表示していた内容をそのまま再表示します。通常は事前にキャッシュしていた内容を表示し、サーバへのリクエストは行いません。
(2) ステートフルWebアプリケーション
Webアプリケーションはステートレスと呼ばれるバラバラな処理と描写を連続して実行することで目的を達成しています。そもそもWebアプリケーション自体、HTTP という「リクエスト−レスポンス」のセット間同士に一切の関連性がない細切れな通信プロトコルを利用して動作しているわけですが、そのWebアプリケーションはある程度決められたやり取りをもって動作していることがよくあります。例えばユーザ情報を入力した内容を使用して会員登録を行ったり、商品をカートに入れて決済を行い購入確定とするショップサイトなどとといった具合です。
これら一連の流れ(フロー)をもって1つの処理内容(アプリケーション)と捉え実装する方法を、ステートレスWebアプリケーションに対し「ステートフル」なWebアプリケーションと呼びます。
ステートフルなWebアプリケーション開発は、既存のステートレス指向なWebアプリケーション開発で常に頭を悩ませる以下の問題に対し、驚くべき単純な解を与えてくれます。
●セキュリティ対策
一連の流れをもって1つのアプリケーションと考えており、いきなり最後の処理 (例えばデータベース書き込み) だけを実施するようなリクエストは排除
●戻るボタン対策
画面遷移の内容(ルート)を完全に制御するため、ブラウザの戻るボタンを押されたとき(及びそれに相当する操作)の挙動まで管理可能
●マルチウィンドウ対策
各ウィンドウごとに状態を保持することが可能であり、セッション情報の混合が起きず管理が容易
ステートフルなWebアプリケーション開発を支援するいくつかのライブラリ、およびフレームワークが登場しています。しかしそれを利用する上で開発を行っていく設計基準、手法にベストプラクティスがないのが現状です。
(3) ステートフルな携帯サイト
ステートフルなアプローチで構築するWebサイトでは、(2)で記載したとおりの恩恵を受けることができます。しかしながら構築するものが携帯端末向けのサイトである場合、以下のような理由でステートフルなWebアプリケーション開発による旨みが減少するだけでなく、「余計なこと」を考える必要があります。
●シングルウィンドウ固定
現在のところ、携帯端末で利用されているブラウザ内で複数のウィンドウを開くような概念は一般的ではありません。一部端末ではマルチウィンドウに対応していたりもするようですが、フルブラウザ (PCサイト閲覧向け) であったりということで今回のような話とは別件になります。したがってマルチウィンドウ対策を考える必要は特にないでしょう。
●戻るボタンの挙動の違い
前述した(1)で示したとおり、携帯キャリアにより戻るボタンの動作が異なります。Docomo、Softbank に関しては PC と同じように考えることができますが、au は完全にページキャッシュによる再描画を行うことが可能であるため、これに対する対策を別途考える必要があります。
●戻るボタンそのものの考え方の違い
私自身あまり携帯端末をヘビィに使うユーザではありませんが(加えて Willcom 端末利用のため PC と同等のように扱う)、携帯端末を利用する場合中央四方キーの左もしくは左側ソフトキーなどを使ってページを戻る(来た道を戻る)ような利用方法がPCブラウザ以上にあるのではないでしょうか。
これはPCブラウザの場合、マウスによるポインタ機能が備わっているため、メニューなどのページ内リンクによる画面遷移が比較的容易であるのに対し、画面内に描写できる量が限られる携帯サイトでは「メニューから項目を選択」→「詳細表示」といった画面遷移が取られていることが多く、結果他項目へ移る際に1つ前のメニューへ戻るために戻るボタンが利用されるというという流れです。
携帯端末における戻るボタン殺してしまうと、PCブラウザ以上に操作感を損なうことなるだけでなく、場合によっては混乱を招く恐れもあるのではないかと推測しています。このあたりのより詳細なお話を予告として、次回に続きます。
今月関西圏で予定している Piece Project としての活動が2つあります。
まず 7/20(金) 京都にて開催されるオープンソースカンファレンス2007に Piece Project としてイベントに参加します。
オープンソースカンファレンス2007 Kansai Piece Framework講演のお知らせ
Piece Frameworkの概要について、セキュリティに関するお話を踏まえつつ解説する予定だそうです。14:00 からということですが、7/20のタイムテーブルを確認して他のイベントとあわせてどうぞ。
また 7/21(土) には、新大阪でオブジェクトリレーショナルマッピングを提供するプロダクト「Piece_ORM」の勉強会を開催。
実際にプログラムコードを書きつつ動作の確認を行っていきます。Piece_Unity サンプルアプリケーションとの電撃合体 (新日風) による実装例も。