RESTful API作成用silexスケルトン silex-simple-restについて

この記事ではvesparny/silex-simple-rest · GitHubを紹介します。

silex-simple-rest

silex-simple-restはReadmeに

A simple silex skeleton application for writing RESTful API.

と書いてあるとおり、RestAPI作成の際に便利なスケルトンです。

これを使うことでキャッシュ・ログディレクトリの配置やHTTPヘッダの設定、JSONデータのパースなどAPI作成時の共通処理の記述を省略し、すぐAPI作成に取り掛かることができます。あと、このスケルトン通りに作ればコントローラのサービス化(http://silex.sensiolabs.org/doc/providers/service_controller.html)も自然にできるので、無駄なコントローラのインスタンスを生成せずに済むのも嬉しい点です。

ことはじめ

インストール方法はreadme通り

git clone https://github.com/vesparny/silex-simple-rest
cd silex-simple-rest
curl http://getcomposer.org/installer | php
php composer.phar install
sqlite3 app.db < resources/sql/schema.sql # デモ使用時のみ必要

とすれば終わりです。 最終行のsqlite3は動作デモ用なので必要なければやらなくても大丈夫です。

あとは適当にサーバを立ち上げてやれば準備完了です。

サンプルとして最初からnotesというapiが実装されているので、sqlite3でapp.dbを作成した場合は動作確認が行えます。

php -S localhost:9001 -t web

としてサーバを立ち上げて、apiにアクセスします。 (-tオプションによってドキュメントルートがwebディレクトリに設定されます。)

curl http://localhost:9001/api/v1/notes
[{"id":"1","note":"one"},{"id":"2","note":"two"},{"id":"3","note":"three"}]

出来ました。

余談ですが、

curl http://localhost:9001/api/v1/notes -sS | jq -C "." | wac
[
  {
    "note": "one",
    "id": "1"
  },
  {
    "note": "two",
    "id": "2"
  },
  {
    "note": "three",
    "id": "3"
  }
]

とすればwindowsでも色付きで整形されたjsonが見れます。

設定するところなど

apiのURL

URLはhttp://localhost:9001/api/v1/...となっています。 apiの部分は$app["api.endpoint"]、 v1の部分は$app["api.version"]で指定されています。 どちらもresources/config/prod.phpにあるのでお好みで書き換えられます。api.foo/v1とするかfoo/api/v1とするか等いろいろ悩みどころです。俺はどっちでもいいけど

app.php

DBなどの設定はsrc/app.phpにあります。

15行目のdate_default_timezone_set('Europe/London');は忘れずにdate_default_timezone_set('Asia/Tokyo');にしましょう。

同じくapp.phpにある

<?php
//accepting JSON
$app->before(function (Request $request) {
    if (0 === strpos($request->headers->get('Content-Type'), 'application/json')) {
        $data = json_decode($request->getContent(), true);
        $request->request->replace(is_array($data) ? $data : array());
    }
});

の処理によってリクエスト中のjsonデータは自動的json_decodeされるので、jsonでも意識せずに $request->request->get("foo");と、あたかも普通にPOSTされてきたデータのように扱うことが出来ます。(http://silex.sensiolabs.org/doc/cookbook/json_request_body.html)

あとはdoctrine, monologの設定を適宜行えば準備完了です。

実装

  1. src/App/RoutesLoader.phpinstantiateControllersメソッドに全コントローラをsharedサービスとして登録
  2. 同じくsrc/App/RoutesLoader.phpbindRoutesToControllersメソッドでURIをコントローラのアクションと紐付ける。
  3. src/App/Controllers/NotesController.phpを参考にコントローラサービスクラスを作成
  4. src/App/Services/NotesService.phpを参考にサービスクラスを作成

で、完了です。デモに沿った内容で書けば迷わないでいけそうです。

参考