これでParse難民も安心!? サーバサイドを拡張できるmobile backendの新機能「スクリプト」を試してみた

[ニフティクラウドmobile backend](http://mb.cloud.nifty.com/)が、サーバサイドにコードを置いて機能拡張ができる「スクリプト機能」を3/1にリリースしたので試してみました。
mobile backendは、Parseからの乗り換え相談窓口を設置するなどParse難民の受け入れに積極的でしたが、Cloud Codeにあたる機能がありませんでした。
しかし、今回のスクリプト機能のリリースで、その部分の問題も解決されたと言えるかもしれません。

どんな機能かを簡単に説明すると

* BaaSのサーバサイドにスクリプトファイルを配置できる
* そのスクリプトファイルをAPIリクエストで実行できる
* リクエストのメソッドやヘッダ、クエリやボディも指定できる

これによって、アプリサイドに実装していたロジックをサーバサイドで実行できるようにして処理を軽くしたり、AndroidとiOSでそれぞれ実装していた共通ロジックを切り出したりできるようになるわけです。
また、アプリサイドで実装すると解析されてしまうリスクのある、ガチャやバトルの判定なんかもサーバサイドに実装することでチート対策ができます。

今回はMonacaを使って試してみました。

### 手順
事前準備：アカウント登録・アプリの作成（省略）
1. スクリプトファイルの作成・アップロード
2. アプリとmobile backendを連携する
3. スクリプト機能部分を実装する

### 1. スクリプトファイルの作成・アップロード
サーバサイドに置くコードはNode.jsのmodule.exportsの形式で記述します。
１ファイル１モジュールとして用意するようです。
例としてはこんな感じ。

```
function myFunc(req, res) {
  res.send("Hello World");
}

module.exports = myFunc;
```
もしくは即時関数でこんな感じ。
(公式ドキュメントではこちらが推奨らしいです。)

```
module.exports = function(req, res) {
  res.send("Hello World");
}
```
Node.jsのコードなので仕様としては他のnpmモジュールも使えるみたいですが、現在はmobile backendのjavascript SDKとsuperagentのみ利用可で、他は今後追加予定とのことです。

コードを作成したら、これをjsファイルとして保存し、コントロールパネルからアップロードします。今回は上のコードを"hello.js"として保存しました。
その際にAPIリクエストする際のメソッドを指定します。
ここでは"GET"を指定しました。
後述しますが、リクエストする際にSDKの関数でも、ここで指定したメソッドを指定します。
"GET"を指定した場合にはQueryを、"POST"や"PUT"を指定した場合はボディを設定してリクエストできるので、用途に合わせて指定してください。
また、ファイルの状態をスタンバイか実行可能のどちらかにしますが、スタンバイだとリクエストできないので、実行可能にします。

### 2. アプリとmobile backendを連携する

monacaで最小限のテンプレートでアプリを作成し、mobile backendのJavascript SDK(2.1.0以上のもの)を[ここからダウンロード](https://github.com/NIFTYCloud-mbaas/ncmb_js/releases)してアプリに追加したら、index.htmlを以下のように書き換えて連携させます。
キーの部分は、コントロールパネルの「アプリ設定」にある自分のアプリケーションキーとクライアントキーに置き換えてください。

```html
<!DOCTYPE HTML>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
    <meta http-equiv="Content-Security-Policy" content="default-src * data:; style-src * 'unsafe-inline'; script-src * 'unsafe-inline' 'unsafe-eval'">
    <script src="components/loader.js"></script>
    <link rel="stylesheet" href="components/loader.css">
    <link rel="stylesheet" href="css/style.css">
    <script>
    </script>
</head>
<!-- 1. SDKの読み込み -->
<script type="text/javascript" src="ncmb.min.js" charset="utf-8"></script>
<script>
  // 2. mobile backendアプリとの連携
  var ncmb = new NCMB("YOUR_APPLICATIONKEY","YOUR_CLIENTKEY");
</script>
<body>
  <script>
    // ここにスクリプト機能を実装する
  </script>
</body>
</html>
```

### 3. スクリプト機能部分を実装する

先ほどのコードに、スクリプト機能へのリクエストを実装していきます。
第一引数に先ほど指定したメソッドタイプ、第二引数にファイル名を指定して、ncmb.Script クラスのexecメソッドを実行します。
リクエストが成功すると、レスポンスのbodyキーにスクリプトファイルでsendに指定した文字列"Hello World"が返ってきます。
他にもヘッダに値を付加したり、JSON形式で返すことも可能のようです。
今回はシンプルに、document.writeで返ってきた文字列を表示してみます。

```html
<!DOCTYPE HTML>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
    <meta http-equiv="Content-Security-Policy" content="default-src * data:; style-src * 'unsafe-inline'; script-src * 'unsafe-inline' 'unsafe-eval'">
    <script src="components/loader.js"></script>
    <link rel="stylesheet" href="components/loader.css">
    <link rel="stylesheet" href="css/style.css">
    <script>
    </script>
</head>
<!-- 1. SDKの読み込み -->
<script type="text/javascript" src="ncmb.min.js" charset="utf-8"></script>
<script>
  // 2. mobile backendアプリとの連携
  var ncmb = new NCMB("YOUR_APPLICATIONKEY","YOUR_CLIENTKEY");
</script>
<body>
  <script>
      // 3. スクリプト機能の実装
      ncmb
      .Script
      .exec("GET", "hello.js")
      .then(function(res){
          // リクエスト成功時の処理。レスポンスはbodyキーに格納されている。
          document.write(res.body);
      })
      .catch(function(err){
          // リクエスト失敗時の処理
          console.log(err);
      });
  </script>
</body>
</html>
```

実行してみると、この通り文字列が表示されていることが確認できます。

![スクリーンショット 2016-03-08 0.26.55.png](https://qiita-image-store.s3.amazonaws.com/0/79789/c2d78a30-92fe-1f50-a559-295f3d9680ab.png)

### まとめ
今回はシンプルに文字を返す例を試しましたが、ヘッダいじったりJsonでレスポンスしたりもできるようなので、作りこみ次第で色々な使い方ができそうです。
スクリプトファイル内でSDKも使えてmobile backendに保存されているデータも簡単に扱えるので、データストアと連携させて、moile backend単体でガチャ機能の実装なんかもできますね。
気が向いたら、次回はもう少し作り込んだ例を試してみたいと思います。