Hack で JSON返すシンプルなマイクロWebアプリケーションフレームワーク書いてみた その(2)

前回とりあえず書いてみたHackで書いたコードですが、

  • strictモードで hh_client check を通したい
  • strictモードで書きたいが Aura.Router が PHP なので Strictモードの指定ができない
  • 高負荷でベンチとると composer がエラーを吐いて hhvm (HipHop VM 3.4.0-dev (rel)) が落ちる

という不満点から改良してみました。

autoload を composer から Aura.Autoload に

loaderは自前で書こうかどうか悩んだんですが、Aura.Autoloadを使うと安定したので、自前で書かずにAura.Autoloadを使うことに。

なので、Hakuを動かすためには composer install が必要ですが、名前空間の定義は app.php で書く形に。

Router を Hack で

とりあえず、マイクロwebアプリフレームワークで最低限必要な、リクエストメソッドと、URIからルーティングできる機能をHackで書きました。preg_matchなどは strictモードでは PREG_SET_ORDER のようなグローバル定数を使うと怒られちゃうので一部 //UNSAFE 指定が必要だったりと、このあたりは妥協。

web/app.php
<?hh // partial

$loader = include(__DIR__ . '/../src/Loader.php');

// add your Namespace to loader like below, if you need.
// $loader->addPrefix('YourVendor', __DIR__ . '/../src');

use Haku\Request;

$app = new Haku\Application();

// simple JSON response
$app->get('/home', () ==> ['message' => 'this page is home']);

// uri parameter
$app->get('/hello/{name}', $name ==> ['message' => $name]);

// with condition
$app->get('/user/{id}', $id ==> ['id' => $id])->addToken(Pair{'id',  '\d+'});

// with query parameter
$app->get('/search', (Request $r) ==> {
        if (!$r->query('q')) {
            http_response_code(400);
        }
        return ['q' => $r->query('q')];
    });

$app->run((new Request()));

ほとんど同じです。loaderが変わったことによる指定の仕方が変わったことと、ルーターをHackで書いたので addToken に渡すパラメータが Pairになったぐらいです。

より速くなったの?

前回までのコードがhhvmをビルドした環境だとセグフォで落ちるようになってしまったため よりstrictモードな構成になったことでどれだけ速くなったかは検証できず。でも、前回同様 PhalconPHP と比べてみると Requests per second で見ると 10% 程度高い値なので、やはり十分速いということは間違いないかなと。

ただし、hhvm構成のほうが php-fpm + phalcon 構成よりメモリ、CPUのリソースを使うように見えました。
これはhhvmをdevでビルドしたからかもしれないので一概に断定はできず。

hh_client 便利

型チェックをしてくれる hh_client は自分で呼ばないといけないので面倒ですが、事前にチェックできるのはやはり便利。
LLなので、チェックでエラーになってても動く場合があといえばあるので CIで必ず忘れずにチェックするとか必要な感じ。

Hack楽しいですね。(辛いけど)