ハイパーメディアAPIハンズオン

## Skeletonインストール

BEAR.Sunday 1.0@devのプロジェクトスケルトンをインストールします。
Auraフレームワークと同じくアプリケーションは独自の名前空間を持つパッケージです。

`Vendor.Application`のフォーマットでアプリケーション名を指定します。

    $ composer create-project bear/skeleton:~1.0@dev MyVendor.MyApp
    $ cd MyVendor.MyApp/
    $ composer install
    
    Loading composer repositories with package information
    Installing dependencies (including require-dev)
      - Installing aura/web (2.0.1)
    ...

    $ phpunit

    OK (3 tests, 6 assertions)

コンソールでWeb（Pageリソースをアクセス)

```
$ php ./bootstrap/web.php get '/?name=BEAR'
code: 200
header:
body:
{
    "greeting": "Hello BEAR",
    "_links": {
        "self": {
            "href": "/?name=BEAR"
        }
    }
}
```

コンテキストを`cli-app`に変更して試してみましょう。

```bootstrap/web.php
<?php

$context = 'cli-hal-app';
require __DIR__ . '/bootstrap.php';
```

```
$ php ./bootstrap/web.php get '/?name=BEAR'
```

webサーバーで確認も

```
$ php -S 0.0.0.0:8080 -t var/www/
```


## aura/sql

データベースを使用するのに[Aura.Sql](https://github.com/auraphp/Aura.Sql)をインストールします。

    composer require aura/sql

`AppModule`から`Aura.Sql`を利用可能にします。`ExtendedPdoInterface`インタf−フェイスに`ExtendedPdoProvider`プロバイダーを束縛します。

```src/Module/AppModule.php

use Aura\Sql\ExtendedPdoInterface;
use Ray\Di\Scope;

class AppModule extends AbstractModule
{
    /**
     * {@inheritdoc}
     */
    protected function configure()
    {
        // aura/sql
        $this->bind(ExtendedPdoInterface::class)->toProvider(ExtendedPdoProvider::class)->in(Scope::SINGLETON);

        // bear/package
        $this->install(new PackageModule(new AppMeta('Ex\Skeleton')));
    }
}
```
```src/Module/ExtendedPdoProvider.php

use Aura\Sql\ExtendedPdo;
use Ray\Di\ProviderInterface;

class ExtendedPdoProvider implements ProviderInterface
{
    /**
     * {@inheritdoc}
     */
    public function get()
    {
        $pdo = new ExtendedPdo(
            'sqlite:' . dirname(dirname(__DIR__)) . '/var/db/db.sqlite'
        );

        return $pdo;
    }
}
```
ExtendedPdo`はPDOを継承したクラスです。ここではsqliteをドライバに使っています。


```src/Resource/App/Person.php

use Aura\Sql\ExtendedPdoInterface;
use Ex\Resource\ResourceObject;
use Ex\Resource\Annotation\Link;

class Person extends ResourceObject
{
    /**
     * @var ExtendedPdoInterface
     */
    private $pdo;

    public function __construct(ExtendedPdoInterface $pdo)
    {
        $this->pdo = $pdo;
    }

    public function onGet($id)
    {
        $stmt = $this->pdo->query('SELECT name FROM person WHERE id=:id');
        $stmt->execute(['id' => $id]);
        $this['person'] = $stmt->fetchAll(\PDO::FETCH_ASSOC);

        return $this;
    }

    /**
     * @Link(rel="new", href="/person{?id}")
     */
    public function onPost($name)
    {
        $stmt = $this->pdo->query('INSERT INTO person(name) VALUES(:name)');
        $stmt->execute(['name' => $name]);
        $this->code = 201; // created
        $this['id'] = $this->pdo->lastInsertId();

        return $this;
    }
}
```

アクセスしてみます。

    $ php ./bootstrap/api.php post '/person?name=BEAR'

## まとめ

リソースのリンクアノテーション`@Link`があるので、関連リンクが表示されています。これはただのデータではありません。**ハイパーメディア**です！単なるCRUD APIではなく、**ハイパーメディア制約**のあるAPIを作成することができたのです。

`ハイパーメディア`はWebのルーツであり、Webの現在であり、そして未来でもあります。BEAR.Sundayはハイパーメディアをネイティブでサポートしています。