余裕があるうちにCakePHPとWPFの相互運用をまとめていく(準備編)

去年末にリリースした、某予約システムですが、CakePHPとWPFの相互運用をしています。この発想は、手始めに Silverlight+WCFの組み合わせで実験 | Moonmile Solutions Blog からありました。サーバー側にLAMP環境を据えて、クライアントでWindowsを使うという仕組みですね。当時から、Web APIはあったのですが、結合の部分はWCFのほうがよいのではないか?と思ってWindows寄りに考えていました。最近は、ASP.NET MVC、Web APIの流れで、WCFを直接扱うよりもRESTfulで送ればよいという流れがあって、艦これ諜報員の場合も単純なJSONで戻してくるので「諜報」が楽ってのもあります。

仕事なので、サーバーに何を使うのかの選定から始めるわけですが、コストの問題やらサーバーのプログラマ調達の問題などがあって、

  • サーバーにLinux+MySQLを使う
  • クライアントにWindowsを使う
  • クライアントにブラウザを使う

というパターンになっています。クライアントがWindowsだけならば、直接MySQLにアクセスしてもよいのですが、ブラウザも含めるとなるとやり取りは、HTMLかjQuery+JSONかってパターンですよね。そこそこ古いブラウザも含めるとなると、HTMLをべたべたに返してやる必要があります。また、もともとのデータベースがMySQLだったこともあって、そのまま移行。レンタルサーバーの運用コストを考えてLinuxを使う、といったところです。まあ、結果論でいえば、Windows Server+ASP.NETの組み合わせでもよかったのでは?と思うときもありますが、それは結果論で。

さて、サーバーの選定と大まかな仕組みを決めたところなのですが、パフォーマンス的にどのくらいかというと、某予約システムでは、1000件/日程度のアクセスしかないので、それほどのパフォーマンスはいりません。これが1000件/秒とか1000件/分とかだったら考え直すのでしょうが、ここはあっさりCakePHPを選択しました。CakePHPがいかに遅いとはいえ(実際遅いのですが)このぐらいのスピードだと耐えられるでしょう。しかし、実装してきてわかったのですが、Web APIをふつうのApplication APIのようにバシバシ呼び出しとレスポンスが悪くなります。当たり前ですね。間にHTTP通信を絡めてしまうし、エンドのCakePHP自体のレスポンスもあるし。なので、ある程度は、APIの呼び出し回数は考慮しないといけません。

image

本来は、ブラウザからCakePHPへアクセスしたかったのですが、諸事情があってブラウザからOriginal に作成した MVC をアクセスしています。ブラウザでの予約は、不特定多数の一般的なお客さんなので、Viewの部分はそれなりにリッチに書かなければいけません。なので、CakePHPの吐き出すソースは何に使うというとおもにWindowsクライアントからのWeb API呼び出しに使います。また、本来ならば Original MVC から直接MySQLへのアクセスを禁止するほうがよいのですが、SELECTに限って許しています。これも諸事情の関係ですね。

なので、CakePHPのView部分に関しては、いろいろ豊富な方法があるのですが一切使っていません。あくまで Web APIに徹する(Windowsクライアントからの呼び出しに応答する)役目を負わせています。

CakePHPからの応答がXML型式になっていますが、これはJSONでも構いません。当時、WindowsクライアントでJSONをパースする方法が(私的に)見当たらなかったのでXMLにしたのですが、実は DataContractJsonSerializer クラス (System.Runtime.Serialization.Json) を使えばOKです。Xml系のオブジェクトになるので、自前の ExDoc と組み合わせて使っています。XMLの構造=クラス構造とはしたくなかった≒面倒だった、というのも理由のひとつですが、システム的にクライアントとサーバーのアップデートは「同時には行えない」ことが分かっていたので、APIからの構造が変わっても古いクライアントでも緩く動く、というシステム構成を作っておくためです。このあたりのテクニックは、cookpad に学んでいます。

Windows クライアントは WPF で作っています。業務用なので Windows フォームでもよかったのですが、先行きタブレット版のストアアプリとかスマートフォン対応を考えると XAML で書いておいたほうがいいですよね。Windows クライアントのほうは社内業務用なので、インストーラ付きでガシガシ作れる状態です。ただし、Windows 7対応ということで、まだWindows 8にはなっていません。

WPF アプリのほうは、MVVM パターンを使っています。なので、なにかの機能を入れて WPF クライアントを拡張しようとすると MVVM+MVC の苦行パターンにはまります。この辛さは半端ではありません。去年の夏の1か月は暑いさなかこの「苦行」をしていました。マスター系のクライアントも MVVM で作っていたので、10テーブルぐらいのマスター画面を WPF で、あと諸々の業務用画面を WPF でという具合ですね。それに対応する CakePHP の Controller をちまちま作るという感じす。もちろん、CakePHP は bake を使って自動生成させるのですが、定型的なブラウザのマスター画面ならいいのですが、ちょっと気の利いたテーブル構成(複数テーブルっていう意味で)とちょっと気の利いたマスター画面を作ろうと思うと、手作業で追加が発生するんですね。当然ですが。まあ、それでも、そこそこのコード量を自動的に吐き出してくれるので、そこそこのスピードでマスター画面が作成できたのはよかったかと。

そのあたりも含めて、CakePHPとWPFの相互運用をテーマにぼちぼちと書き下していく予定です。ちなみに、機能拡張の部分はそれぞれが分離されているので非常に楽です。CakePHPのWeb APIになっているので、ブラウザでAPIの結果をXML型式で確認できるとかデバッグも多少楽になっています。複雑なSQLをどう解くのか(どうテストするのか?)という点では、PHPUnitを使うのか、Web API経由でMSTestを使うのかという問題もありますが、いまのところ MSTest 一本でやっています。

カテゴリー: CakePHP, WPF パーマリンク