第1章 クラウドアプリの開発

1.1. クラウド開発

1.1.1. 概要

Red Hat Mobile Application Platform ホスト型 (RHMAP) の中心的なコンセプトの 1 つはクラウドアプリです。クラウドアプリは、モバイルデバイスにデプロイされたクライアントアプリとビジネスロジックおよびデータが含まれるバックエンドシステム間の通信を処理するサーバーサイドアプリケーションです。

クラウドアプリは Node.js を使用して開発されます。 Node.js は、高速でスケーラブルなネットワークアプリケーションを簡単に構築できるようにする、Chrome の JavaScript ランタイムに基づいて構築されたプラットフォームです。Node.js は軽量さと効率性を実現するイベント駆動の非ブロッキング I/O モデルを使用し、分散されたデバイスで実行するデータ集約型リアルタイムアプリケーションに最適です。

Node.js 開発に精通していない場合は、Node Beginner Website を参照することをお勧めします。

1.1.2. クラウドアプリ構造

クラウドアプリが RHMAP で作成された場合、その新しく作成されたクラウドアプリは実質的には事前設定された Node.js アプリケーションです。事前設定された対応するクライアントアプリも生成された場合、クラウドアプリにはすべての基本的な設定 (ルート) が含まれるため、クライアントアプリとクラウドアプリは同期されます。また、クラウドアプリをホストするインフラストラクチャーもインプレース状態 (MBaaS) にあり、簡単にアクセスできます。

設定とインフラストラクチャーがすべてインプレース状態にあるため、クラウドアプリは MBaaS にデプロイできます。また、追加コードを必要とせずにクライアントアプリの要求をルーティングできます。上級 Node.js 開発者がサーバーを再設計したり、独自のサーバーを実装したりする場合、これは、application.js ファイル内のコードを操作することによって可能になります。

注記

アプリのメインエントリーポイントを表すファイルには必ず application.js という名前を付ける必要があります。

クラウドアプリでは次のファイルがデフォルトで提供されます。

1.1.2.1. application.js

このファイルは、アプリケーションが MBaaS (クラウド実行環境) にデプロイされたときに呼び出されます。ほとんどの場合は、このファイルを変更する必要はありません。このファイルは、クライアントからの fh.cloud() 要求を処理し、適切にルーティングするよう設定されます。

1.1.2.2. package.json

クラウドアプリの設定ファイルは、主に依存関係の管理に使用されます。サードパーティーの Node モジュールを使用している場合、それらのモジュールはこのファイルで指定されます。

関連項目:

1.1.3. サンプル

クラウドアプリは非常に簡単に準備できます。Studio で新しいプロジェクトを作成するときに Hello World Project テンプレートを試したり、GitHub (feedhenry-templates/helloworld-cloud) でテンプレートのソースコードを探したりすることにより単純なサンプルを使用できます。以下にテンプレートの簡単な概要を示します。

最初の手順は application.js でカスタムルートを設定することです。

app.use('/hello', require('./lib/hello.js')());

参照される hello.js ファイルでは、特定のルートのロジックを定義します。

var express = require('express');
var bodyParser = require('body-parser');
var cors = require('cors');

function helloRoute() {
  var hello = new express.Router();
  hello.use(cors()); // enables cross-origin access from all domains
  hello.use(bodyParser()); // parses POST request data into a JS object

  hello.post('/', function(req, res) {
    res.json({msg: 'Hello ' + req.body.hello});
  });
  return hello;
}
module.exports = helloRoute;

$fh.cloud を使用したこのエンドポイントへのクライアントサイド呼び出しは以下のようになります。

$fh.cloud({
    path: 'hello',
    data: {
      hello: 'World'
    }
  },
  function (res) {
    // response handler
  },
  function (code, errorprops, params) {
    // error handler
  }
);

1.2. 環境

1.2.1. 環境とは

環境は、プロジェクト、サービス、フォーム、およびアプリの開発サイクルを個別のステージに論理的に分離する方法です。環境はライフサイクル管理の重要な要素です。

たとえば、プロジェクトには Dev、UAT、および Production の 3 つのステージが含まれることがあります。各ステージは環境により表されます。環境の数と種類はプラットフォームで設定可能であり、ドメインごとに変更できます。

1.2.2. 環境とビジネスオブジェクトの対話

App Studio で環境が使用される領域は以下のとおりです。

  • Projects (Apps を含む)
  • Services
  • Forms
  • Admin > Auth Policies

環境にアクセスせずにこれらの領域にアクセスすると、以下のような警告が表示されます。

Core Structure

1.2.3. 環境がない —  機能が制限される

App Studio でプロジェクト、サービス、フォーム、およびアプリに関連するほとんどのアクションを実行するには、1 つまたは複数の環境にアクセスできる必要があります。

現在環境にアクセスできない場合は、以下の理由が考えられます。

  • 現在のチームメンバーシップにより環境の使用が許可されない
  • 管理者がまだ環境をセットアップしていない

1.2.3.1. チームメンバーシップの更新

環境にアクセスするには、ユーザー (またはドメインの管理者) が以下の操作を実行する必要があります。

  • Admin > Teams 領域に移動する
  • メンバーになっているチームを変更し、そのチームのメンバーに Admin > Environment ビジネスオブジェクトへのアクセスを与える

チームの管理の詳細については、ここをクリックしてください。

1.2.3.2. 管理者環境のセットアップ

チームがセットアップされ、メンバーシップが適切な場合は、管理者に連絡してください。環境へのアクセスをチームによって与える前に、管理者が環境をセットアップする必要があります。

1.2.4. 他のリソース

1.3. クラウドアプリでの Node.js の使用

1.3.1. 概要

本書では、Node.js モジュールをクラウドアプリに含め、使用する方法について説明します。Red Hat Mobile Application Platform (RHMAP) では、クラウドアプリを開発するためにレジストリーで利用可能な Node.js パッケージのモジュールを使用できます。パブリックレジストリー (npmjs.com) では、フレームワーク、コネクター、およびさまざまなツールを含む数千のパッケージを見つけることができます。

NPM Web サイト

RHMAP 自体の機能の一部はノードモジュールとして公開されます。たとえば、プラットフォームで新しいクラウドアプリを作成する場合、デフォルトでは package.json に Mobile Backend As A Service (MBaaS) の基盤となる fh-mbaas-api という名前のモードモジュールが含まれます。

1.3.2. Node.js モジュールの使用

アプリにある機能が必要であり、一から作成したくない場合は、npmjs.com で既存のモジュールを探すことをお勧めします。

たとえば、Mongoose ODM フレームワークを使用する場合は、レジストリーの mongoose パッケージの公式ページ (npmjs.com/package/mongoose) を参照してください。

npmjs.com Mongoose パッケージの詳細

プロジェクトでパッケージの最新バージョンを使用する場合は、クラウドアプリのディレクトリーで以下のコマンドを実行してパッケージをローカルにインストールし、依存関係としてクラウドアプリの package.json ファイルに追加します。

npm install --save mongoose

または、以下の例のように、dependencies オブジェクトの最後で依存関係を追加することにより依存関係を package.json に手動で追加します。

{
    "name": "my-fh-app",
    "version": "0.2.0",
    "dependencies": {
        "body-parser": "~1.0.2",
        "cors": "~2.2.0",
        "express": "~4.0.0",
        "fh-mbaas-api": "~4.9.0",
        "mocha": "^2.1.0",
        "request": "~2.40.0",
        "mongoose": "~4.1.12" // added mongoose dependency
    }
}

この時点で、パッケージで提供されるモジュールを使用できます。多くの場合、npmjs.com のパッケージページには、使用方法とドキュメンテーションへのリンクが含まれます。すべてのモジュールで共通な次の手順では、コードでモジュールを必須にして使用できるようにします。

var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/my_database');
...

この例では、データベース URL はソースでハードコーディングされます。ただし、より一般的なシナリオでは開発ライフサイクルの異なるステージ (開発、テスト、本番稼働) に応じて異なるデータベースを使用します。これは、環境変数で設定値を定義することにより実現できます。

1.3.3. 環境変数

ホスト名、ユーザー名、パスワードなどのクラウドアプリの設定の部分がライフサイクルステージで異なる場合は、環境変数を使用してこのような設定値を設定できます。これにより、コードを変更せずに設定を変更できるようになります。Studio において各クラウドアプリには Environment Variables セクションがあり、変数を作成または削除したり、値を設定したり、アプリの実行中インスタンスに変数をプッシュしたりできます。

環境変数

環境変数は、異なる値を異なる環境にプッシュする機能と組み合わせると特に有用です。たとえば、テスト用と本番稼働用に異なるデータベースホストを使用できます。他の利点は、 機密性がある設定情報をアプリケーションのコードベース外に格納できることです。

クラウドアプリでは、環境変数は process.env オブジェクトを介してアクセスできます。環境変数を使用するよう変更された Mongoose 接続呼び出しの前の例は以下のようになります。

mongoose.connect('mongodb://' + process.env.MONGO_HOST + '/' + process.env.MONGO_DB);

1.4. npm を使用した Node.js 依存関係の管理

1.4.1. 概要

npm (ノードパッケージマネージャー) は Node.js 用の依存関係管理ツールであり、Node.js アプリケーションを開発するために必要になります。原則として、npm は Maven、Cocoapods、NuGet などの他の依存関係管理システムに似ています。

  • プロジェクトでは標準化されたファイル (Node.js の場合は package.json) で依存関係が宣言される
  • パッケージは 1 か所 (registry.npmjs.org にある npm レジストリー) でホストされる
  • 依存関係バージョンは、ワイルドカードまたは範囲を使用して明示的に指定できる
  • 推移的な依存関係のバージョンは自動的に決定または修正できる (npm-shrinkwrap ファイルの使用を参照)
  • インストール後にパッケージがローカルでキャッシュされる (node_modules フォルダー)

クラウドアプリでの Node.js モジュールの使用については、クラウドアプリでの Node.js モジュールの使用を参照してください。

1.4.2. npm とアプリのステージ

クラウドアプリをデプロイする場合は、アプリの環境で npm コマンドが実行され、アプリの依存関係がダウンロードおよびインストールされます。以下のことに注意してください。

  • 初めてクラウドアプリがデプロイされる場合は、完全な npm install が実行されます。このため、アプリの最初のデプロイメントには非常に時間がかかることがあります。
  • 以降の各デプロイにおいて、package.json ファイルが以前のデプロイから変更された場合は、npm update が実行されます。
  • package.json に変更が加えられない場合、npm コマンドは実行されません (updateinstall も実行されません)。
  • npm を完全に再実行する場合は、以下のように削除ステージを実行します。

    • Studio でクラウドアプリの Deploy セクションの Clean Stage チェックボックスをオンにします。
    • fhc を使用している場合は、--clean オプション ( つまり、fhc app stage <app-id> <env-name> --clean) を使します。

1.4.3. npm のベストプラクティス

npm を使用した基本的なベストプラクティスは、ノードモジュールでバージョン管理がどのように機能するかを理解し (The semantic versioner for npm を参照)、package.json の依存関係に対して * を使用しないことです。

ローカルで開発する場合に役に立つヒントは、npm (npm install request --save など) を使用してモジュールをインストールするときに --save フラグを使用することです。--save フラグを使用すると、インストールされたバージョンの package.json の依存関係セクションに新しいモジュールが追加されます。また、shrinkwrap ファイルの使用もお勧めします。

1.4.3.1. npm-shrinkwrap ファイルの使用

npm-shrinkwrap.json ファイルは、パッケージの推移的な依存関係のバージョンをロックダウンするため、パッケージのインストール時に使用する各依存関係の適切なバージョンを制御できます。

shrinkwrap ファイルを作成するには、以下のコマンドを実行します。

npm shrinkwrap

生成された npm-shrinkwrap.json ファイルをクラウドアプリのルートディレクトリーに配置します。RHMAP のアプリで npm install が呼び出されると、shrinkwrap ファイルで定義されたバージョンが使用されます。

shrinkwrap の詳細については、公式な npm ドキュメンテーション (Lock down dependency versions) を参照してください。

1.4.4. node_modules のアップロード

RHMAP では、node_modules ディレクトリーをコミットし、クラウドアプリで使用できます (ただし、これは推奨される方法ではありません)。この場合、アプリがステージングされても npm はまったく実行されず (clean オプションが指定されている場合であっても)、アップロードしたモジュールはアプリを実行するために使用されます。ただし、ネイティブのノードモジュールは実行するのと同じアーキテクチャー (RHMAP のインスタンスによって異なる可能性があります) でコンパイルする必要があります。

1.5. Node.js バージョンの設定

1.5.1. fhc の使用

最初に、fhc の最新バージョンを用意します。

npm install -g fh-fhc

次に fhc ランタイムコマンドを使用して、環境で利用可能なランタイムを確認します。

fhc runtimes --env=dev

このコマンドを実行すると、4.4.7 などのバージョンが出力されます。

左側にはランタイムの名前が示され、右側には特定のバージョンが示されます。

fhc app stage --app=<APP_GUID> --runtime=<node version>

ステージ中にアプリのランタイムを設定するには、<node version> (4.4.7 など) を追加します。

これにより、ノードのアプリのランタイムが v4.4.7 に設定されます。

別のランタイムに変更するには、ランタイムの引数をステージコマンドに再び追加します。

1.5.2. Studio の使用

Studio のデプロイ画面では、アプリが設定された現在のランタイムを確認できます。また、ここで新しいランタイムを設定し、アプリをデプロイすることもできます。