ニフクラmBaaSお役立ちブログ

スマホアプリ開発にニフクラmBaaS。アプリ開発に役立つ情報をおとどけ!

スクリプト機能を使って複数のクラスデータを一回で取得する

3月にリリースしたスクリプト機能を使って、どんなことができるのか試していきたいと思います。

mBaaSのデータストアではRESTfulの原則に従っていますので、一つのURLごとに一つのクラスが割り当てられています。そのため、複数のクラスからデータを取得する場合、複数回のネットワークアクセスが必要です。

そこでバッチ処理を使って複数のデータ取得をまとめて行うようにしてみます。今回はJavaScript SDKから試してみたいと思います。

まずはアプリ側のコードです。YOUR_APPLICATION_KEY、YOUR_CLIENT_KEYはそれぞれ読み替えてください。

var application_key = 'YOUR_APPLICATION_KEY';
var client_key      = 'YOUR_CLIENT_KEY';
var ncmb = new NCMB(application_key, client_key);

// バッチ処理を行う変数。クラス名、検索条件を指定しています。
var batch = [
  {"cName": "Feed",
    "cs": [{operation: "equalTo", column: "title", value: "XXXXXXXXXXX"}]
  },
  {"cName": "Item",
    "cs": [{operation: "equalTo", column: "objectId", value: "2sqsmvv6JE953EwI"}]
  },
  {"cName": "TODO",
    "cs": [{operation: "equalTo", column: "todo", value: "Test task"}]
  }
];

// スクリプトを実行します。
ncmb.Script
  .data({"batch": batch})
  .exec("POST", "batchSelect.js")
  .then(function(res){
    // 実行後処理
    console.log(JSON.parse(res.body));
  })
  .catch(function(err){
    // エラー処理
    console.error('Batch select failed.', err);
  });

バッチ処理として、検索条件を送信します。処理結果は一つの文字列(res.body)の中に入ってきます。

サーバ側のスクリプト

続いてサーバ側のコードです。コードはサイズを小さくするために変数名を短くしています。アップロード時にはコメントもなくしています。

var NCMB = require('ncmb');
module.exports = function(req, res) {
  // NCMBの設定
  var a = 'YOUR_APPLICATION_KEY';
  var c = 'YOUR_CLIENT_KEY';
  var ncmb = new NCMB(a, c);
  
  // req.body.batchを順番に処理します
  Promise.all(req.body.batch.map(function(w) {
    
    return new Promise(function(resolve, reject) {
      // クラス名を割り当てます
      var cName = ncmb.DataStore(w.cName);
      
      // 検索条件を処理します
      for (var i = 0; i < w.cs.length; i++) {
        var ope = w.cs[i];
        // 今回はequalToにしか対応していません
        switch (ope.operation) {
          case "equalTo":
            cName = cName.equalTo(ope.column, ope.value);
        }
        // 検索します
        cName.fetchAll()
          // 検索が成功した場合はresolveをコールします
          .then(function(data) {
            resolve(data);
          })
          // 検索が失敗した場合はrejectをコールします
          .catch(function(err) {
            reject(err);
          })
      }
    });
  }))
  .then(function(results) {
    // 検索が終わったらJSONデータとして返却します
    res.status(200).json(results);
  }, function(err) {
    res.status(503).json({"error": err});
  })
};

これを実行すると、次のようにレスポンスが返ってきます。


リクエストはだいたい1秒くらいでレスポンスが返ってきます。3つのAPIをコールするとネットワークコネクションの作成からデータの受信など、2秒以上かかるのではないでしょうか。バッチ処理化することでトラフィックやコネクション数を抑えられるようになります。