Alloy Modelの学習・その4(REST API)の続き
前回、REST APIのData Bindingを使ってみたのですが、
そのときに課題として残していたエラーハンドリングなどレスポンスに対する処理に関してと、開発中にAPIエンドポイントを分離したい場合の方法についてメモ。
レスポンスに対する処理
napp.alloy.adapter.restapi を使う際の、エラー処理を含むレスポンスの処理方法を調べてみました。
napp.alloy.adapter.restapiのリポジトリに掲載されている例では引数を受け取っていませんでしたが、各メソッドでは、以下のように success
と error
のコールバックを受け取ることができます。
function doOpen() { memos.fetch({ success : function(models, response){ Ti.API.debug('memo fetch() - success = ' + models + ' / ' + response); }, error : function(models, response){ Ti.API.debug('memo fetch() - error = ' + models + ' / ' + response); } }); }
各 success
と error
コールバックは、サーバーからのレスポンスのHTTPステータスコードによって判断されて呼びだされるため、基本的に意識する必要はありません。
受け取ったモデルの加工だったりエラーに対する処理のほか、通信中のローディング画面の制御などもここでハンドリングできますね。
コールバックの形
操作対象がCollectionなのかModelなのかによって、コールバックには大きく2種類の形があるようです。
メソッド | コールバック | コールバックの形 |
---|---|---|
Collection.fetch() | success error |
function(models, response) |
Model.save() Model.destroy() |
success error |
function(model, response) |
各コールバックの第1引数は、主に操作したモデルデータを受け取るようです。
次に、共通している response
には、Titanium.Network.HTTPClientの responseText
が入ってくるようです。通信をJSONでやりとりする場合は、必要に応じて JSON.parse()
するなどして扱うことになると思います。
コールバックの形を見るに、 responseText
以外の情報は受け取っていないようなので、例えばもしアプリ側でもHTTPステータスコードが必要な場合は、あらかじめレスポンスボディに含めるなどする必要がありそうです。
iOSとAndroidでエンドポイントを分ける
特にPCローカルのサーバーと、iOSとAndroidのシミュレータ/エミュレータで通信確認をする場合のメモです。
iOSのシミュレータでは 127.0.0.1
で開発しているMac側で立ち上げているAlloyModelStudyRestStubにアクセスできるのですが、AndroidのエミュレータやGenymotionの場合、 127.0.0.1
は端末自体を示すらしく、 10.0.2.2
か 10.0.3.2
といったIPになるようです。
モデルの URL
を書き換えれば対応できますが、その都度実施するのも面倒なので、あらかじめ config.json に設定しておき、そのURLを使うようにしました。
app/config.json
{ ... "os:android env:development": { "API_URL": "http://10.0.3.2:4321/memos" }, "os:ios env:development": { "API_URL": "http://127.0.0.1:4321/memos" }, ... }
config.json で設定できる値は、 os:android
や os:ios
といったプラットフォームをあらわすオブジェクトに、動作環境をあらわす env:development
などを組み合わせることで、「Androidのエミュレータの場合」「iOSのエミュレータの場合」に使う値、というようにバリエーションをつけることができます。
それをモデルの中で参照することで、環境ごとに異なるURLを使えるようになりました。
app/models/memo.js
exports.definition = { config: { columns: { "id": "integer", "contents": "text", "priority": "text" }, adapter: { type: "restapi", collection_name: "memo", "idAttribute": "id" }, "URL": Alloy.CFG.API_URL, // <== config.jsonに定義したURL "debug": 1 }, ... };
env:production
などと組み合わせれば、本番環境向けビルドで使うURLも設定できます。
なお、以前はモデルの中でグローバルな Alloy
オブジェクトを参照できなかったので、こちらの記事( AlloyのModelでREST APIからデータを取得する - Qiita )のように一手間必要だったようですが、Alloy 1.4.0?あたりから参照できるようになったようです。
Backbone.js的な対処方法
モデル側のURLの指定を変更する方法とは別に、Backbone.js的に、モデル操作時にオプションとしてURLを渡すという対処方法もあります。
その場合は、 Collection.fetch({url: <url>})
・ Model.save(<params>, {url: <url>})
・ Model.destroy({url: <url>})
といったあたりのメソッドを使えば良いようです。
エンドポイントを動的に変更するようなケースがあれば、使いみちがあるかもしれません。
まとめ
APIのレスポンスに関しては、自前で用意するAPIであれば設計段階で調整できますが、既成サービスのものなどを使う場合はいじりようがないので、実戦使用するときに、また色々と検証しようと思います。
Appcelerator Titanium Smartphone App Development Cookbook - Second Edition
- 作者: Jason Kneen
- 出版社/メーカー: Packt Publishing
- 発売日: 2015/11/30
- メディア: Kindle版
- この商品を含むブログを見る