BEAR.SundayでParse.comをラップしてAPIアプリを作る
はじめに
最近、以下の構成で趣味プロダクトを作ろうとしています。
- バックエンドには Parse.com を利用
- BEAR.Sunday アプリで Parse.com と連携して単純な CRUD 以外の API を実装
- フロントエンドは AngularJS
Parse.com はデータストアと REST API を提供してくれるクラウドサービス(BaaS)です。
月 100 万リクエストぐらいまで無料らしいので、小規模な趣味プロダクトなら十分無料で使えそうです。
この記事では、BEAR.Sunday アプリで Parse.com をラップして独自の API を提供する方法を紹介したいと思います。
Parse.com は Cloud Code という機能でサーバサイドの処理を拡張できるらしいので、それを使えば BEAR.Sunday アプリを自分でホスティングする必要はなくなりそうですが、今回は BEAR.Sunday の勉強も兼ねているのでこのような構成で作ります。
Parse.com にアプリを準備
- Parse.com に サインアップ
- アプリを作成
- Data Browser の
+ Add Class
ボタンからとりあえずUser
クラスを追加 -
Add a row
ボタンからユーザーのレコードを 1 つ追加
BEAR.Sunday プロジェクトを作成する
次に、BEAR.Sunday アプリのプロジェクトを作成しましょう。composer で簡単に作成できます。
$ composer create-project bear/skeleton My.App
$ cd My.App
$ composer install
プロジェクト名は
[ベンダ名].[アプリ名]
と付けると名前空間とかをいい感じにしてくれます。ここではMy.App
というプロジェクト名でインストールしています。
プロジェクトが作成できたら、Users
アプリケーションリソースを作成しましょう。
<?php
// src/Resource/App/Users.php
namespace My\App\Resource\App;
use BEAR\Resource\ResourceObject;
class Users extends ResourceObject
{
public function onGet()
{
$this->body = 'test';
return $this;
}
}
仮に、ただ 'test'
という文字列を返すだけの API としました。
実行してみましょう。
$ php bootstrap/contexts/api.php get "app://self/users"
200 OK
content-type: ["application\/hal+json; charset=UTF-8"]
cache-control: ["no-cache"]
date: ["Tue, 23 Dec 2014 10:13:28 GMT"]
[BODY]
test
動いてますね。
Parse.com の PHP 用 SDK を組み込む
PHP SDK には、Parse.com 公式の parse/php-sdk を使用します。
$ composer require parse/php-sdk
SDK の初期化に、Parse.com の
- Application ID
- REST API Key
- Master Key
が必要です。ダッシュボードの [Settings] → [Keys] で確認してください。
SDK 初期化
この SDK の初期化処理を BEAR.Sunday のどこに書くべきか迷ったのですが、App
クラスに初期化用のメソッドを追加して @PostConstruct
アノテートすることでしっくりくる感じに書けました。
<?php
// src/App.php
namespace My\App;
use BEAR\Package\Provide\Application\AbstractApp;
use Parse\ParseClient;
use Ray\Di\Di\PostConstruct;
final class App extends AbstractApp
{
/**
* @PostConstruct
*/
public function onInit()
{
$appId = 'Application ID';
$restKey = 'REST API Key';
$masterKey = 'Master Key';
ParseClient::initialize($appId, $restKey, $masterKey);
}
}
Users アプリケーションリソースを修正
Users リソースを修正して実データを取得できるようにしましょう。
<?php
// src/Resource/App/Users.php
namespace My\App\Resource\App;
use BEAR\Resource\Code;
use BEAR\Resource\ResourceObject;
use Parse\ParseException;
use Parse\ParseUser;
class Users extends ResourceObject
{
public function onGet($objectId = null)
{
$query = ParseUser::query();
if (!is_null($objectId)) {
try {
$query->get($objectId);
} catch (ParseException $e) {
$this['error'] = [
'code' => $e->getCode(),
'message' => $e->getMessage(),
];
$this->code = Code::NOT_FOUND;
return $this;
}
}
$users = [];
foreach ($query->find() as $user) {
$users[] = json_decode($user->_encode(), true);
}
$this->body = $users;
return $this;
}
}
実行してみましょう。
$ php bootstrap/contexts/api.php get "app://self/users"
200 OK
content-type: ["application\/hal+json; charset=UTF-8"]
cache-control: ["no-cache"]
date: ["Tue, 23 Dec 2014 11:12:10 GMT"]
[BODY]
0 => array(
objectId TeDsTS7UxB,
createdAt => array(
date 2014-12-23 10:04:40,
timezone_type 2,
timezone Z,
),
updatedAt => array(
date 2014-12-23 10:04:45,
timezone_type 2,
timezone Z,
),
username test,
),
[VIEW]
{
"0": {
"objectId": "TeDsTS7UxB",
"createdAt": {
"date": "2014-12-23 10:04:40",
"timezone_type": 2,
"timezone": "Z"
},
"updatedAt": {
"date": "2014-12-23 10:04:45",
"timezone_type": 2,
"timezone": "Z"
},
"username": "test"
},
"_links": {
"self": {
"href": "http://localhost/app/users/"
}
}
}
ちゃんと取得できました!
ユーザの作成も出来るようにする
Users
リソースに onPost()
を追加して、ユーザの作成も出来るようにしてみましょう。
public function onPost($username, $password, $email)
{
$user = new ParseUser();
$user->set('username', $username);
$user->set('password', $password);
$user->set('email', $email);
try {
$user->signUp();
$this->body = json_decode($user->_encode(), true);
} catch (ParseException $e) {
$this['error'] = [
'code' => $e->getCode(),
'message' => $e->getMessage(),
];
$this->code = Code::BAD_REQUEST;
}
return $this;
}
作成してみる。
$ php bootstrap/contexts/api.php post "app://self/users?username=name&password=pass&email=user@test.com"
200 OK
content-type: ["application\/hal+json; charset=UTF-8"]
cache-control: ["no-cache"]
date: ["Tue, 23 Dec 2014 11:23:56 GMT"]
[BODY]
objectId NhOZYYKoBC,
createdAt => array(
date 2014-12-23 11:23:56,
timezone_type 2,
timezone Z,
),
updatedAt => array(
date 2014-12-23 11:23:56,
timezone_type 2,
timezone Z,
),
username name,
email user@test.com,
[VIEW]
{
"objectId": "NhOZYYKoBC",
"createdAt": {
"date": "2014-12-23 11:23:56",
"timezone_type": 2,
"timezone": "Z"
},
"updatedAt": {
"date": "2014-12-23 11:23:56",
"timezone_type": 2,
"timezone": "Z"
},
"username": "name",
"email": "user@test.com",
"_links": {
"self": {
"href": "http://localhost/app/users/?username=name&password=pass&email=user%40test.com"
}
}
}
再度取得してみる。
$ php bootstrap/contexts/api.php get "app://self/users"
200 OK
content-type: ["application\/hal+json; charset=UTF-8"]
cache-control: ["no-cache"]
date: ["Tue, 23 Dec 2014 11:25:41 GMT"]
[BODY]
0 => array(
objectId TeDsTS7UxB,
createdAt => array(
date 2014-12-23 10:04:40,
timezone_type 2,
timezone Z,
),
updatedAt => array(
date 2014-12-23 10:04:45,
timezone_type 2,
timezone Z,
),
username test,
),
1 => array(
objectId NhOZYYKoBC,
createdAt => array(
date 2014-12-23 11:23:56,
timezone_type 2,
timezone Z,
),
updatedAt => array(
date 2014-12-23 11:23:56,
timezone_type 2,
timezone Z,
),
email user@test.com,
username name,
),
[VIEW]
{
"0": {
"objectId": "TeDsTS7UxB",
"createdAt": {
"date": "2014-12-23 10:04:40",
"timezone_type": 2,
"timezone": "Z"
},
"updatedAt": {
"date": "2014-12-23 10:04:45",
"timezone_type": 2,
"timezone": "Z"
},
"username": "test"
},
"1": {
"objectId": "NhOZYYKoBC",
"createdAt": {
"date": "2014-12-23 11:23:56",
"timezone_type": 2,
"timezone": "Z"
},
"updatedAt": {
"date": "2014-12-23 11:23:56",
"timezone_type": 2,
"timezone": "Z"
},
"email": "user@test.com",
"username": "name"
},
"_links": {
"self": {
"href": "http://localhost/app/users/"
}
}
}
ちゃんと作成されてますね!
一応ダッシュボードでも確認。ユーザがちゃんと増えてます。
まとめ
ここまで出来たらあとは BEAR.Sunday 側で Parse.com のデータを加工して返してくれる API とか、関連するデータを一括で変更する API とか、いろいろ簡単に作れそうですね!
BaaS が提供してくれる API では基本的な CRUD しかできないので、基本的な処理を BEAR.Sunday 側で実装しておけば、クライアント側はほぼビューを用意するだけで良くなるんじゃないかと画策しています。(複数のクライアントアプリを簡単に作れる)
BEAR.Sunday も初心者だし Parse.com の SDK もまだ使い方をちゃんと理解できてないので、この記事で紹介したサンプルコードは完成度が低いと思いますが、少しでもお役に立てば幸いです。
Discussion