リソース志向フレームワークBEAR.SundayでDoctrine\ORMを使ってみた。
DB接続設定がべた書きでテスト時にどうやって切り替えたらいいのかまだわからない上に、(主にBEARの)使い方として間違ってないのか?と微妙に不安ながら、一応動いたところまでメモ。
※思考過程ダダ漏れの、ただのメモです。
参考にしたのはこちら
https://github.com/BEARSunday/bearsunday.github.io/wiki/workshop#di%E3%81%A7%E3%83%AD%E3%82%B0%E3%82%92%E6%8F%90%E4%BE%9B
http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/tutorials/getting-started.html
アプリケーションの想定
シンプルなメモAPI。
認証等はひとまず考えない。
apiにget/post/update/deleteのリクエストを投げるとDBのデータをいい感じに取得・作成・更新・削除できればいいな。
BEAR.Sundayインストール
https://github.com/BEARSunday/bearsunday.github.io/wiki/workshop#%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB
の通り。プロジェクト名は仮でMy.NoteAppとする。
composer create-project bear/skeleton My.NoteApp
cd My.NoteApp
composer install
AppResourceでの利用イメージを考える
Doctrine\ORMのEntityManagerを、BEARのAppResourceでこんな感じで利用できたらいいなーという目標を立てた。
// src/Resource/App/Note.php
namespace My\NoteApp\Resource\App;
use BEAR\Resource\ResourceObject;
class Note extends ResourceObject
{
public function onGet($id)
{
$note = $this->entityManager->find('...', $id);
$this['note'] = ['body' => $note->getBody()];
return $this;
}
}
Providerを書く
ワークショップのMonologProviderと同じように、Doctrine\ORM\EntityManagerを作ってくれるProviderを作ることにした。
mysql環境を作るのが面倒なので仮でsqliteで。
DBファイルの配置先はBEAR.Packageのvar以下を眺めて、仮でvar/dbに置くことに決めた。
Doctrine\ORM\EntityManagerの作り方は下記を参考に適当に コピペ 書いた。
http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/tutorials/getting-started.html#obtaining-the-entitymanager
// src/Module/Provider/DoctrineORMProvider
namespace My\NoteApp\Module\Provider;
use Doctrine\ORM\Tools\Setup;
use Doctrine\ORM\EntityManager;
use Ray\Di\ProviderInterface;
use BEAR\Sunday\Inject\AppDirInject;
class DoctrineORMProvider implements ProviderInterface
{
use AppDirInject;
public function get()
{
$config = Setup::createAnnotationMetadataConfiguration(array(__DIR__."/../Entity"), false);
$conn = array(
'driver' => 'pdo_sqlite',
'path' => $this->appDir . '/var/db/db.sqlite',
);
$entityManager = EntityManager::create($conn, $config);
return $entityManager;
}
}
追記:
@kenji_sさんがBEAR式の設定を注入する方法をブログに書いてくださっています。
BEAR.SundayでDoctrine2のORMを使ってみた(改)
http://blog.a-way-out.net/blog/2014/07/11/bear-sunday-doctrine/
ProviderをDIに登録
src/Module/AppModule.php(最初から存在している)に自作のDoctrineORMProviderを登録。
// src/Module/AppModule.php
protected function configure()
{
$this->install(...); // 最初から書いてある部分
$this->bind('Doctrine\ORM\EntityManager')->toProvider('My\NoteApp\Module\Provider\DoctrineORMProvider'); // bind,toProviderともに最初のバックスラッシュは要らなかった
}
entityを書く
entityの置き場所は他に適切なところが思いつかなかったのでsrc配下にEntityディレクトリを作ってそこに置くことにする。(実はProviderを書いた時点で決めてあって、設定にそれ書いてた)
下記を参考にidとbodyだけのNoteエンティティを書く。
http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/tutorials/getting-started.html#starting-with-the-product
普段Symfony2でDoctrine2のentity書くときとは少しアノテーションの書き方が違うので要注意。
// src/Entity/Note.php
namespace My\NoteApp\Entity;
/**
* @Entity
* @Table(name="note")
*/
class Note
{
/**
* @var int
* @Id
* @Column(type="integer")
* @GeneratedValue
*/
private $id;
/**
* @var string
* @Column(type="text")
*/
private $body;
// getter,setterは省略
}
本当はここでDBにテーブル作成するんだけど、BEAR.Sundayでのコマンドの書き方がわからなかった(汗)のと、Doctrine\ORMのスクリプト書くのも面倒だったので、コマンドでサクッと済ませた。
ついでにテストデータも登録。
sqlite3 var/db/db.sqlite
> create table note(id INTEGER PRIMARY AUTOINCREMENT NOT NULL, body TEXT NULL);
> insert into note(body) values('test body1');
> insert into note(body) values('test body2');
> .exit
実際のAppResourceを書く
ここまでで、最初に想定した利用法でDoctrine\ORM\EntityManagerが使えるようになったはず!
早速NoteリソースにEntityManagerをセットして使ってみよう。
私が作るNoteというAppResourceは、どのメソッドでもEntityManagerを使う想定(本来の使い方とは違うかもしれない?)なので、コンストラクタインジェクションでいいだろう。
// src/Resource/App/Note.php
namespace My\NoteApp\Resource\App;
use BEAR\Resource\ResourceObject;
use Doctrine\ORM\EntityManager;
use Ray\Di\Di\Inject;
class Note extends ResourceObject
{
/**
* @var EntityManager
*/
private $entityManager;
/**
* @param EntityManager $entityManager
* @Inject
*/
public function __construct(EntityManager $entityManager)
{
$this->entityManager = $entityManager;
}
public function onGet($id)
{
$note = $this->entityManager->find('\My\NoteApp\Entity\Note', $id);
$this['note'] = ['body' => $note->getBody()];
return $this;
}
}
実際にNoteをgetしてみる。
php bootstrap/contexts/api.php get 'app://self/note?id=1'
[BODY]
note => array(
body test body1
),
[VIEW]
{
"note": {
"body": "test body1"
},
"_links": {
"self": {
"href": "http://localhost/app/note/?id=1"
}
}
}
やったー!無事に動きました:)
(次回に続く http://qiita.com/77web@github/items/aa4d4e4faca38300eaec )