laravel x モバイルアプリ

42
laravel x モバイルアプリ

Upload: masaki-oshikawa

Post on 24-Jan-2017

891 views

Category:

Technology


0 download

TRANSCRIPT

Page 1: laravel x モバイルアプリ

laravel x モバイルアプリ

Page 2: laravel x モバイルアプリ

発表内容

• アプリ開発者という生き物について

• アプリ開発のDB事情

• モバイルアプリ用Web API 実装 tips

Page 3: laravel x モバイルアプリ

pochikawa

starfruits_j Azione Co., Ltd.

Oshikawa

Page 4: laravel x モバイルアプリ

• 元Webデザイナ

• iOSアプリ開発

• たまにWebも触る

• PHP7は未経験

• SQLが嫌い

Page 5: laravel x モバイルアプリ

• 元Webデザイナ

• iOSアプリ開発

• たまにWebも触る

• PHP7は未経験

• SQLが嫌い

Page 6: laravel x モバイルアプリ
Page 7: laravel x モバイルアプリ

which.photos

Page 8: laravel x モバイルアプリ

ヤラナイカスプラトゥーンのフレンドのオンライン状態をチェックしたり通知してくれるアプリ

他 > littlegleam.com

Page 9: laravel x モバイルアプリ

発表内容

• アプリ開発者という生き物について

• アプリ開発のDB事情

• モバイルアプリ用Web API 実装 tips

Page 10: laravel x モバイルアプリ

アプリ開発者とはどんな生物? (所感です)

• ローカルでは主にSQLite

• アップデートの壁があるので、仕様変更はあまりしない(したくない)

• サーバサイドのように負荷分散等考えなくて良いので、あまりチューニングとかしない(したくない)

• Viewはアプリ側にあるので、たまにしかサーバサイドは触らない

• Swiftばっかり書いてると、Swift以外のコードは隠蔽したくなる

Page 11: laravel x モバイルアプリ

つまりたまにしかSQL書かない

Page 12: laravel x モバイルアプリ

忘れます!

Page 13: laravel x モバイルアプリ

SQL組み立てめんどい!

$sql = 'SELECT * FROM `laravel` WHERE ';

if ($user_id) { $sql .= ' `user_id` = ' . $user_id; } else { $sql .= ' 1 = 1'; }

Page 14: laravel x モバイルアプリ

連想配列で組み立てるクエリビルダ

$arr = [];

if ($user_id) { $arr['user_id'] = $user_id; }

$db->select('table', $fields, $arr);

Page 15: laravel x モバイルアプリ

$arrってなんだっけ?

• resultがarrayだったり?

• 久々に触ると仕様を確認したりコードを呼んだりしなければならない

• SQL読んだ方が分かりやすい

• SQLが複雑になると、もはや読めもしない

Page 16: laravel x モバイルアプリ

発表内容

• アプリ開発者という生き物について

• アプリ開発のDB事情

• モバイルアプリ用Web API 実装 tips

Page 17: laravel x モバイルアプリ

Realmrealm.io

Page 18: laravel x モバイルアプリ

RealmのModel

// Define your models like regular Swift classes class Dog: Object { dynamic var name = "" dynamic var age = 0 }

// Use them like regular Swift objects let mydog = Dog() mydog.name = "Rex" print("name of dog: \(mydog.name)")

// Persist your data easily let realm = try! Realm() try! realm.write { realm.add(mydog) }

https://realm.io/docs/swift/latest/

Page 19: laravel x モバイルアプリ

RealmのSelect

let tanDogs = realm.objects(Dog).filter("color = 'tan'") let tanDogsWithBNames = tanDogs.filter("name BEGINSWITH ‘B'")

※メソッドチェインでクエリを組み立てられる

https://realm.io/docs/swift/latest/#queries

Page 20: laravel x モバイルアプリ

よく使うクエリをclassメソッドで実装すると便利

class Dog: Object { dynamic var name = "" dynamic var age = 0 dynamic var color = "white" class func tanDogs() -> Results<Dog> { let realm = try! Realm() return realm.objects(Dog).filter("color = 'tan'") } }

Dog.tanDogs().sorted("age", ascending: false)

https://realm.io/docs/swift/latest/#queries

Page 21: laravel x モバイルアプリ

モデルを書くことで仕様が決まりモデルを見れば仕様が理解できる

コードが出来上がる👏

Page 22: laravel x モバイルアプリ

PHPでもメソッドチェインでクエリ書けないものか?

Page 23: laravel x モバイルアプリ

そう、laravelならね

Page 24: laravel x モバイルアプリ

発表内容

• アプリ開発者という生き物について

• アプリ開発のDB事情

• モバイルアプリ用Web API 実装 tips

Page 25: laravel x モバイルアプリ

可視性の高い設計

• サーバ側とアプリ側でモデルを統一化したい

• Realmと酷似しているのでGood!

• レコードを連想配列にしてJSON出力

• ModelのtoJson();でOK!レスポンスをJSONにするのも簡単。

• アプリ側はRealmにマッピングして保存

Page 26: laravel x モバイルアプリ

users.password等、ユーザに渡せない情報

• Modelのhidden propertyで指定

Page 27: laravel x モバイルアプリ

アプリ側の実装

class User: Object { dynamic var id = "" dynamic var name = "" }

https://realm.io/docs/swift/latest/#queries

Page 28: laravel x モバイルアプリ

laravel側の実装

/** * @property string $id // ID * @property string $name // 名前 * @property string $password // パスワード */ class User extends Model {

protected $hidden = ['password'];

}

https://realm.io/docs/swift/latest/#queries

Page 29: laravel x モバイルアプリ

deleted_at -> isDeleted

• カラムにないプロパティはget~~Attributeで追加できる

Page 30: laravel x モバイルアプリ

アプリ側の実装

class User: Object { dynamic var id = "" dynamic var name = “" dynamic var isDeleted = false }

https://realm.io/docs/swift/latest/#queries

Page 31: laravel x モバイルアプリ

laravel側の実装

/** * @property string $id // ID * @property string $name // 名前 * @property string $deleted_at // 削除日時 */ class User extends Model {

protected $hidden = [‘deleted_at’];

function getIsDeletedAttribute() { return (boolean) ($this->deleted_at); }

}

https://realm.io/docs/swift/latest/#queries

Page 32: laravel x モバイルアプリ

画像読み込みのストレスを減らす

• ローディング中に表示するプレースホルダ用にサムネイルをbase64したバイナリを返す

Page 33: laravel x モバイルアプリ

laravel側の実装

/** * @property string $id // ID * @property string $name // 名前 */ class User extends Model {

function getImageURLAttribute() { return sprintf('%s/images/%d.jpg',

Config::get('app.url'), $this->user_id); }

function getThumbnailAttribute() { $bin = file_get_contents(

$this->thumbnail_file_path); return base64encode($bin); }

}

https://realm.io/docs/swift/latest/#queries

Page 34: laravel x モバイルアプリ

時差を考慮する

海外展開する場合等に困るので、 ISO8601で返すようにしてあげると安全

class User extends Model {

public function getCreatedAtAttribute($date) { return date('c', strtotime($date)); } public function getUpdatedAtAttribute($date) { return date('c', strtotime($date)); } }

https://realm.io/docs/swift/latest/#queries

Page 35: laravel x モバイルアプリ

RESTfulは注意

• リクエストの回数が増える

• フリースポット等で予期せぬ200が返ります

• statusをjsonに含めてチェックする等してあげた方が無難

Page 36: laravel x モバイルアプリ

エラー発生時

App::error(function(Exception $exception, $code) use($self) { Log::error($exception);

$res = array( 'status' => 0, 'code' => $code, 'message' => $exception->getMessage(), 'trace' => $exception->getTraceAsString(), );

if ($self->isDebug()) { $res['sql_history'] = $self->sql_history; $res['post'] = $_POST; $res['get'] = $_GET; } return Response::json($res, $code); });

https://realm.io/docs/swift/latest/#queries

Page 37: laravel x モバイルアプリ

AfterFilter

$this->afterFilter(function($route, $request, $response) use($self) { $data = $response->getOriginalContent(); if (!$data) { $data = array(); } if (is_array($data)) { if (!isset($data['status'])) { $data['status'] = 1; } if ($self->isDebug()) { $data['sql_history'] = $self->sql_history; $data['post'] = $_POST; $data['get'] = $_GET; } $response->setContent($data); } });

https://realm.io/docs/swift/latest/#queries

Page 38: laravel x モバイルアプリ

レスポンスがタイムアウトするかも

• 通信状態が悪い場合、画像/動画のアップロードでタイムアウトが発生するが、PHPはアップロードが完了した時点でinsertしてしまう

• 極端に大きな通信はcommit用のAPIを用意して、送信完了のレスポンスを受け取ってからcommitする

Page 39: laravel x モバイルアプリ

ちょっとした変更でリクエストが複数回

• 通信量、速度のみでなく失敗のリスクも高まる

• JSON-RPC使う

• githubにあります (未確認)

Page 40: laravel x モバイルアプリ

laravelって素晴らしい!😉

• 優秀なQuery Builder

• 暗黙的でフレキシブルなORM

• SQLなんか書かなくて良い!

• 他FWに比べて並列分割のテーブルも扱いやすい

• API構築にも最適化されている

Page 41: laravel x モバイルアプリ

laravelって素晴らしい?😅

• CREATE TABLE必要

• Schema Builderもあるけど、やっぱり忘れる

• 複数テーブルをJOINし始めると辛い

• PHP7の新機能の活用に期待!

Page 42: laravel x モバイルアプリ

ご静聴ありがとう ございました!