読者です 読者をやめる 読者になる 読者になる

tanaka's Programming Memo

プログラミングについてのメモ。

SlimPHP:Slim マイクロフレームワークで REST アプリケーションを作成する(5)複数のレスポンス・フォーマットのサポート

PHP 勉強メモ

前へ


IBM developerWorks Slim マイクロフレームワークで REST アプリケーションを作成するを参考に、SlimPHPのスケルトンアプリから作成します。コードはSlimPHP3用に書き換えています。


SlimPHP:Slim マイクロフレームワークで REST アプリケーションを作成する(4)認証 - tanaka's Programming Memo からの続きです。

複数のレスポンス・フォーマットのサポート

リクエストされているContent-Typeに応じて、返すデータの書式を変更することができます。

以下、参考元のソースをSlim3ように書き換えたものです。 src/routes.php を開いて、「$app->get('/articles', ・・・」から始まるコードを以下のように変更してください。

// articlesへのルートを設定する
$app->get('/articles', function($request, $response, $args) {
    try {
        // 一覧を取得
        $articles = R::find('articles');

        // リクエストされたContent-Typeを取得
        $mediaType = $request->getHeader('Content-Type')[0];
        if ($mediaType == 'application/xml') {
            // XMLで結果を返す
            $xml = new SimpleXMLElement('<root/>');
            $result = R::exportAll($articles);
            foreach($result as $r) {
                $item = $xml->addChild('item');
                $item->addChild('id', $r['id']);
                $item->addChild('title', $r['title']);
                $item->addChild('url', $r['url']);
                $item->addChild('date', $r['date']);
            }
            echo $xml->asXml();
            // XMLを返すためのヘッダを設定
            return $response->withHeader('Content-Type', 'application/xml');
        } else if (($mediaType == 'application/json')) {
            // JSONでエンコードした結果を返す
            echo json_encode(R::exportAll($articles));
            // JSONを返すためのヘッダを設定
            return $response->withHeader('Content-Type', 'application/json');
        }
    }
    catch (Exception $e) {
        return $response
            ->withStatus(400)
            ->withHeader('X-Status-Reason', $e->getMessage());
    }
})->add(new CAuthentication());

動作テスト

動作を確認しています。

  • FirefoxでHTTP Resource Testを起動
  • URI欄に http://0.0.0.0:8080/articles と入力
  • Method欄を GET にする
  • Client Request欄から[Header]を選択
  • [Add]を押す
  • コンボボックスを[Content-Type]、[application/xml]に設定
  • 以上ができたら、[Submit]を押す

成功すると、一番下のBody欄にXMLで結果が表示されます。続けて、JSONもテストしましょう。

  • [application/xml]を[application/json]に変更
  • [Submit]を押す

結果がJSONを文字列にエンコードしたものがBody欄に表示されれば成功です。

POSTも対応させる

新規記事の追加時にも、XMLに対応させましょう。Content-Typeがapplication/xmlの場合は、simplexml_load_string()で送信されるデータをXMLで解釈して処理します。

データの返信も同様にXMLの機能を追加します。

src/routes.php を開いて、「$app->post('/articles', ・・・」から始まる行を以下のように修正してください。

// /articles フォルダーへのPOSTリクエストを登録
$app->post('/articles', function ($request, $response, $args) {
  try {
    $mediaType = $request->getHeader('Content-Type')[0];
    $body = $request->getBody();

    if (strpos($mediaType, 'application/xml') === 0){
      $input = simplexml_load_string($body);
    } elseif (strpos($mediaType, 'application/json') === 0) {
      $input = json_decode($body);
    }

    // articleレコードの作成と記録(ここはそのまま)
    $article = R::dispense('articles');
    $article->title = (string)$input->title;
    $article->url = (string)$input->url;
    $article->date = (string)$input->date;
    $id = R::store($article);

    // 結果を返す
    if (strpos($mediaType, 'application/xml') === 0) {
      $xml = new SimpleXMLElement('<root/>');
      $result = R::exportAll($article);
      foreach($result as $r) {
        $item = $xml->addChild('item');
        $item->addChild('id', $r['id']);
        $item->addChild('title', $r['title']);
        $item->addChild('url', $r['url']);
        $item->addChild('date', $r['date']);
      }
      echo $xml->asXml();
      return $response->withHeader('Content-Type', 'application/xml');
    } elseif (strpos($mediaType, 'application/json') === 0) {
      echo json_encode(R::exportAll($article));
      return $response->withHeader('Content-Type', 'application/json');
    }
  } catch (Exception $e) {
    return $response
        ->withStatus(400)
        ->withHeader('X-Status-Reason', $e->getMessage());
  }
});

動作テスト

FirefoxのHTTP Request Testを起動して、以下の通りテストしましょう。

<?xml version="1.0"?>
<root>
  <title>XML Add Test</title><url>http://0.0.0.0:8080/articles</url><date>2016-03-2</date>
</root>
  • [Headers]を押す
  • コンボボックスを[Content-Type]と[application/xml]にする
  • [Submit]を押す

以上で、成功すると、Bodyに新規に登録されたデータがXML形式で表示されます。itemタグとidが新しく追加されているのが確認できます。

引き続き、JSONのテストです。

  • Client Request欄の[Representation]を押す
  • テキストエリアを以下に書き換える
{"title":"JSON Add Test","url":"http:\/\/0.0.0.0:8080\/articles","date":"2016-03-2"}
  • [Headers]を押す
  • [application/xml]を[application/json]に変更
  • [Submit]を押す

以上で、JSONのデータが登録されます。成功すると、一番下のBody欄にJSONで新しく追加されたデータが表示されます。id要素が追加されているのが確認できます。

まとめ

以上で、簡単なSlimPHPを使ったREST APIチュートリアルは完了です。参考にした
Slim マイクロフレームワークで REST アプリケーションを作成する のまとめなども読んでみてください。

認証は省略しましたが、自前で全ての機能を実装するのは大変な上に、セキュリティ的にリスクを抱える可能性が高いので、
Sentinel Manual :: Cartalyst などのライブラリを利用するのが良さそうです。


前へ