URIルーティング処理の生成

<追記>
とりあえず今はsuwaggaを使ったほうがいいかな。

# 概要
URIルーティング処理を生成するツールを使ってREST APIの作成を楽チンにする。
大まかな流れは以下。

1. REST用のテストphpファイルの配置
2. ルーティング処理を生成するためのコンフィグファイルを作成
3. ツールが設定ファイルを読み込んでソースコードを生成

# 背景,経緯
ちょっとしたツールにもREST APIを要求されるようになってきた(マイクロサービス化?)。
REST対応させるとURIルーティングが必要になってくるが、いつもPHPフレームワークを使わない(使いたくない..)で開発するので
いつもURIルーティング機能の実装が面倒でしょうがない。
Laravelを使った事あったけども、ちょっと以下を思った。

* ちょっとしたツールにまでフレームワーク使うのはなんか大げさ、シンプルな構成じゃなくなっちゃう。
* もし仮に間違ったルーティング内容を書いた場合、Webアクセスするまで気付きにくく、最悪トップページすら表示されなくなってしまう。
* ルーティング処理のソースを見ても現状のルーティング内容を把握しづらい。まぁわかるけど。。


# trutの導入
上記の課題を解決するために[trut](https://github.com/simpart/trut)というツールを使用する。
trutはフレームワークのように予め用意された共通の関数やクラス等を提供するのではなく、ソースコード自体を自動生成するツール。
これを使ってURIルーティングを生成すればREST機能の実装が楽になる(はず)。

## 特徴

### コード生成処理をモジュール化
trut自体は生成機能を持たない。
コードの生成機能はモジュールをtrutに組み込む(インストール)事で生成が可能になる。
trutは単に生成用モジュールを管理するツール、器みたいなもん。
なので用途に合わせてモジュールを選択すればいい感じのコードが生成出来る。
もし希望の生成モジュールがなければ自分で作ってtrutにインストールすれば良い。

### アプリ開発者はURIルーティングのコードを直接触らない
生成までの流れとしては以下。

1. trutの生成モジュールに必要な情報(コンフィグファイル)を渡してあげる。
2. それをモジュールが読み込みチェックする。<br>もしこの時点で何か異常を検知したらエラーとなりコードの生成は行われない(※)。
3. 問題ないならコードを生成する。

※生成モジュール側に事前チェック機能が実装されている必要がある。

URIルーティングなんてWebシステムの中ではインフラ部分の機能なんだからそんな機能をデバッグしている時間が勿体無い。
一瞬でコードが生成されて、動作も正しいならば開発者はコア機能の開発に集中出来る。

### ルーティング内容の把握 
生成用のコンフィグファイルはYAML形式で記載する。
コンフィグファイルを確認すれば現在のルーティング内容がわかる(下の方で具体的に)。
trutはCLIのツールだけどWebUIに対応すればルーティング内容の把握がもっとしやすくなるはず。

## インストール
dockerのcentos:centos6で実施。

必要なパッケージのインストール

```bash
yum -y update
yum -y install gcc make php php-pear php-devel libyaml libyaml-devel git
pecl install YAML
```

PHPでYAMLを使用可能にする

```diff:/etc/php.ini
+ extension=yaml.so
```

trutのインストール

```bash
git clone https://github.com/simpart/trut.git
cd trut/tool    
./install.sh
```

# REST API開発
実際にtrutを使ってURIルーティングを実装する。

### 準備

Apacheサーバの導入

```bash
yum -y install httpd
mkdir /var/www/html/test
```

```diff:/etc/http/conf/httpd.conf
<Directory "/var/www/html">
    Options Indexes FollowSymLinks
-    AllowOverride None
+    AllowOverride All
    Order allow,deny
    Allow from all
</Directory>
```

```bash
service httpd start
```

生成モジュールのインストール

```bash
cd /tmp
git clone https://github.com/simpart/simplinerot-php.git
trut mod add ./simplinerot-php
```

今回使用するのはルーティングテーブルを単純に線型探索で検索してリクエストURIにマッチすれば、
マッチした宛先を呼び出すルーティング処理を生成するモジュール。

### テスト用PHPファイルの配置
今回は'AAA'とか文字列を返すだけの簡単なAPIを配置する。

```bash
mkdir /var/www/html/test/src
touch /var/www/html/test/src/aaa.php
```

```php:/var/www/html/test/src/aaa.php
<?php
$ret = array('msg' => 'AAA');
echo json_encode($ret);
```

同じようにbbb.php , ccc.phpを作っておく。

```bash
/var/www/html/test/src
 ├ aaa.php
 ├ bbb.php
 └ ccc.php
```

### コンフィグファイルの作成
コンフィグの記法はモジュール毎に異なる。
今回使用したSimpLineRotモジュールでは1次階層のキーバリューで記載すれば良い。

```yaml:/var/www/html/test/route.yml
# リクエストURI : 宛先への絶対パス
/test/aaa/ : /var/www/html/test/src/aaa.php  # 実在するファイルを指定しないとエラーになる。
/test/bbb/ : /var/www/html/test/src/bbb.php
/test/ccc/ : /var/www/html/test/src/ccc.php
__NMATCHED__ : /var/www/html/test/src/nothingtodo.php
```

YAML形式なのでソースコードを眺めるよりかはルーティング内容を確認しやすいはず。
NMATCHEDはroute.ymlに定義されているルーティング内容のいずれにもマッチしなかった場合の宛先で
必ず指定する必要がある。今回は使用しないのでnothingtodo.phpの中身は"<?php"のみ。

### ソース生成

```bash
mkdir /var/www/html/test/route
cd /var/www/html/test/route
trut gen ../route.yml        # trut gen <コンフィグファイルへのパス> [-o 出力先]
```

### APIコール
Apacheの設定

```vim:/var/www/html/test/.htaccess
RewriteEngine On
RewriteBase /test/
RewriteRule (.*)$ /var/www/html/test/route/route.php [L]
```

aaa呼び出し

```bash
curl http://{ipaddress:port}/test/aaa/
{"msg":"AAA"}
```

/test/bbb/なら"BBB"が返るし/test/ccc/なら"CCC"が返る。
新たに追加したりURIを変更したい場合はroute.ymlを編集してもう一回trut genすれば良い。
ソースに直接書き込む事がなくなったのでルーティング処理に関して言えば楽なったと思う。

# 今後
今後は生成モジュールのバリエーションを増やしていく予定。
今回のデモではPHPのルーティング処理を生成して実装の手間を省かせたけども、
他の言語や◯◯フレームワークのルーティング処理生成をやってみるかも。

あとテーブル探索のアルゴリズムを高速化したり、リクエストURIの正規表現に対応したり、、
そこらへんは自分以外の誰かが作った方が良いものが出来ると思う。

trutはルーティング機能の生成に特化しているツールってわけではないので、
ルーティング以外の機能を生成したり、
もっと言えばソースコード以外(ドキュメントとか)を生成してもおもしろいかも。