Compute Engine と REST を使用したモバイルアプリの構築

Compute Engine でモバイル バックエンドを実行し、モバイルアプリとバックエンド サーバー間の通信プロトコルとして REST を使用することには、いくつかの利点があります。

  • オンプレミスまたは仮想マシン上で実行されている既存のサービスを Google Cloud に移行する最速の方法です。
  • 仮想マシンとサーバーの構成がすべて管理できます。
  • サードパーティ ライブラリが使用できます。
  • オートスケーラーを構成して、仮想マシンの数を必要な規模にスケーリングできます。

Compute Engine でサービスを実行することの欠点は、サーバーのメンテナンスや更新を行わなければならないことです。

このチュートリアルでは、例として Stickynotes というモバイルアプリを構築する作業を一通り行います。このサンプルアプリは REST を使用して、Compute Engine で実行しているバックエンド サービスに接続します。

Stickynotes には、フロントエンドのモバイルアプリとバックエンド サービスのコードが含まれています。これらは次のワークフローで連携します。

  1. ユーザーがモバイルアプリを使用して、テキスト フィールドにメッセージを入力します。
  2. アプリからバックエンド サービスの REST エンドポイントにメッセージが送信されます。
  3. バックエンド サービスは、draw2d ライブラリを使用してテキスト メッセージを含む画像を作成します。
  4. バックエンド サービスからモバイルアプリに画像が返されます。
  5. メッセージが埋め込まれた画像がモバイルアプリに表示されます。

クライアント アプリは iOS アプリであり、バックエンド サービスは Go プログラミング言語で記述されています。

目標

このチュートリアルでは、次の方法を示します。

  • バックエンド サービスの REST エンドポイントに接続する iOS モバイルアプリを作成する。
  • Compute Engine で REST バックエンド サービスを構成し、実行する。

費用

このチュートリアルでは、Google Cloud の課金対象のコンポーネントである Compute Engine インスタンスを使用します。

料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを作成できます。 GCP を初めてご利用の場合には、無料トライアルをご利用いただけます。

始める前に

  1. Google アカウントにログインします。

    Google アカウントをまだお持ちでない場合は、新しいアカウントを登録します。

  2. Cloud Console のプロジェクト セレクタページで、Cloud プロジェクトを選択または作成します。

    プロジェクト セレクタのページに移動

  3. Google Cloud プロジェクトに対して課金が有効になっていることを確認します。プロジェクトに対して課金が有効になっていることを確認する方法を学習する

以下のソフトウェアをインストールします。

  • Git
  • Xcode 7.2 以降
  • Go
    • Go が PATH 変数で指定されたパスにインストールされていることを確認してください。通常は /usr/local/go/bin です。

サンプルコードのクローンを作成する

次のコマンドを実行して、サンプルコードのクローンを作成します。

git clone https://github.com/GoogleCloudPlatform/ios-docs-samples.git

次に、/solutions/stickynoteapi/REST ディレクトリに移動して、このソリューションのサンプルコードを探します。

サーバーをローカルで実行する

/stickynoteapi/REST/Go ディレクトリで、次のコマンドを実行します。

sh SETUP

次の出力が表示されます。

1. Set gopath and search path
2. Get the server and client dependencies
3. Build the server and client
4. Stop any previously-running instances of the server
5. Start the server
6. Run the client
2016/03/02 11:34:48 OK: message.png
7. Open the image in message.png

このセットアップ中に、「Remember the milk.」というフレーズを使用してサーバーをテストするローカル クライアントも実行されます。これにより、対応する画像を含む message.png ファイルがサーバーによって生成されます。

Remember the milk.

コマンドライン クライアントを使用して独自のメッセージに基づく画像を生成するには、次のコマンドを実行します。

./client "This is a test..."

/stickynoteapi/REST/Go/go/src/server/server.go ファイルには、REST サーバーを実行するコードが含まれています。main 関数でルートレベル ディレクトリのハンドラが定義され、ポート 8080 のトラフィックがリッスンされます。

func main() {
	http.HandleFunc("/stickynote", handler)
	http.ListenAndServe(":8080", nil)
	//http.ListenAndServeTLS(":443", "ssl.crt", "ssl.key", nil)
}

サーバーは受信リクエストを handler 関数に転送します。この関数は次の処理を行います。

  1. REST リクエストからテキスト メッセージを抽出します。
  2. sticky.go で定義された関数を使用して、テキスト メッセージに基づいて画像を構築します。
  3. REST レスポンスでクライアントに画像を返します。
func handler(w http.ResponseWriter, r *http.Request) {
	var sticky Sticky
	sticky.Message = r.FormValue("message")
	sticky.Centered = false
	stickyBytes, err := sticky.DrawPNG(512, 512)
	if err == nil {
		w.Write(*stickyBytes)
	}
}

次のセクションでクライアント アプリのテストに使用するため、ローカル サーバーは稼働したままにしてください。

ローカル サーバーでの iOS クライアントの実行

  1. stickynoteapi/REST/Objective-C/ ディレクトリにある stickynotes.xcodeproj を Xcode で開きます。
  2. [Product] > [Run] を選択し、クライアント アプリをビルドして起動します。
  3. テキスト フィールドにメッセージを入力し、リターンキーをタップします。

メッセージを含む黄色の付箋の画像がテキスト フィールドの下に表示されます。

これはテストです...

バックエンド サービスのロケーションは、ファイル StickyNotesViewController.m で設定されています。テスト用として、これはポート 8080 のローカルホストに初期設定されています。

static NSString * const kHostAddress = @"localhost:8080";

テキスト フィールドにメッセージを入力して [Return] をタップすると、メッセージがクエリ文字列にエンコードされ、REST リクエストでサーバーに送信されます。アプリに REST レスポンスが返されると、生成された画像が抽出されて画像ビューに表示されます。次のコードは、これらのタスクを処理するアクションを示します。

- (IBAction) textFieldDidEndEditing:(UITextField *)textField
{
  NSString *queryString = [NSString stringWithFormat:@"http://%@/stickynote?message=%@",
                           kHostAddress,
                           [textField.text urlencode]];
  NSURL *URL = [NSURL URLWithString:queryString];
  _request = [NSMutableURLRequest requestWithURL:URL];

  NSURLSession *session = [NSURLSession sharedSession];
  _task = [session dataTaskWithRequest:_request
                     completionHandler:
           ^(NSData *data, NSURLResponse *response, NSError *error) {
             UIImage *image = [UIImage imageWithData:data];
             dispatch_async(dispatch_get_main_queue(), ^{
                              self.imageView.image = image;
                            });
           }];
  [_task resume];
}

Compute Engine でのサーバーの実行

Compute Engine 上でサーバーをホストするには、compute インスタンスを作成します。

  1. Cloud Console で、[VM インスタンス] ページに移動します。

    [VM インスタンス] ページに移動

  2. [インスタンスを作成] をクリックします。
  3. [名前] を sticky-rest に設定します。
  4. [ブートディスク] の [変更] をクリックし、ブートディスクの構成を開始します。
  5. [Public images] タブで [Google Drawfork Debian GNU/Linux 9] を選択します。

  6. [選択] をクリックします。
  7. [ファイアウォール] で [HTTP トラフィックを許可する] と [HTTPS トラフィックを許可する] を選択します。
  8. [作成] をクリックしてインスタンスを作成します。

インスタンスへのクライアント リクエストを許可するために、ファイアウォール ルールを作成します。

  1. Cloud Console の [ファイアウォール] ページに移動します。

    [ファイアウォール] ページに移動

  2. [ファイアウォール ルールの作成] ページで、次の情報を入力します。

    • 名前: sticky-rest
    • ターゲットタグ: http-server
    • ソース IP の範囲: 0.0.0.0/0
    • プロトコルとポート: tcp:8080
  3. [作成] をクリックします。

インスタンスでサーバーを起動するには、サーバーコードのクローンを作成し、セットアップ スクリプトを実行します。

  1. 仮想マシン インスタンスのリストで、接続するインスタンスの行にある [SSH] をクリックします。

    インスタンス名の横にある SSH ボタン。

  2. VM インスタンスの IP アドレスをメモしておきます。このアドレスは、[外部 IP] の列に表示されます。
  3. インスタンスに Git をインストールします。

    sudo apt update
    sudo apt install git
    
  4. Go ツールをインストールします。

    sudo wget https://storage.googleapis.com/golang/go1.10.linux-amd64.tar.gz
    sudo tar -C /usr/local -xzf go1.10.linux-amd64.tar.gz
    export PATH="/usr/local/go/bin:${PATH}"
    
  5. Stickynotes サーバーコードのクローンを作成します。

    git clone https://github.com/GoogleCloudPlatform/ios-docs-samples.git
    
  6. インスタンスで Stickynotes サーバーを開始します。/solutions/stickynoteapi/REST/Go ディレクトリで、次のコマンドを実行します。

    sh SETUP
    

クライアント アプリを構成して実行するには:

  1. Xcode で StickyNotesViewController.m を編集して、ローカルホストを前のステップでメモした Compute Engine インスタンスの外部 IP フィールドの値に変更します。

    // static NSString \* const kHostAddress = @"localhost:8080";
    static NSString \* const kHostAddress = @"[YOUR-INSTANCE-EXTERNAL-IP]:8080";
    
  2. [File] > [Save] を選択して、変更内容を保存します。

  3. [Product] > [Run] を選択し、クライアント アプリをビルドして起動します。

  4. テキスト フィールドにメッセージを入力し、リターンキーをタップします。

メッセージを含む黄色の付箋の画像がグレーの背景に置き換えられます。

リモート サーバーでテスト中...

クリーンアップ

このチュートリアルで使用するリソースについて、Google Cloud Platform アカウントへの課金が発生しないようにする手順は次のとおりです。

プロジェクトの削除

課金をなくす最も簡単な方法は、チュートリアル用に作成したプロジェクトを削除することです。

プロジェクトを削除するには:

  1. Cloud Console で [リソースの管理] ページに移動します。

    [リソースの管理] ページに移動

  2. プロジェクト リストで、削除するプロジェクトを選択し、[削除] をクリックします。
  3. ダイアログでプロジェクト ID を入力し、[シャットダウン] をクリックしてプロジェクトを削除します。

インスタンスの削除

Compute Engine インスタンスを削除するには:

  1. Cloud Console で、[VM インスタンス] ページに移動します。

    [VM インスタンス] ページに移動

  2. sticky-rest インスタンスのチェックボックスをクリックします。
  3. [削除] をクリックしてインスタンスを削除します。

デフォルトのネットワークのファイアウォール ルールの削除

ファイアウォール ルールを削除するには:

  1. Cloud Console で、[ファイアウォール ルール] ページに移動します。

    [ファイアウォール ルール] ページに移動

  2. 削除するファイアウォール ルールのチェックボックスをクリックします。
  3. [削除] をクリックして、ファイアウォール ルールを削除します。

次のステップ

このサンプルでは、REST を使用して Compute Engine で実行するコードにモバイルアプリを接続する基本的な方法を示します。このサンプルの機能を拡張して実際のアプリに使用する場合は、次の拡張を追加することを検討してください。

  • 静的な外部 IP アドレスをサーバーに追加する - デフォルトでは、Compute Engine インスタンスに関連付けられる外部アドレスは一時的なものです。本番環境アプリでは、静的な外部 IP アドレスをインスタンスに関連付けます。詳細については、インスタンスの IP アドレスの構成をご覧ください。

  • 認証情報を使用して HTTPS サーバーに接続する - モバイルアプリに認証情報を使用してサーバーから認証を受けるように要求することで、このモバイルアプリのみがバックエンド サービスを呼び出せるようにします。HTTP ではなく暗号化された HTTPS プロトコルを使用して、ユーザーがサーバーに送信するデータのプライバシーを保護します。これには、NGINX サーバーを SSL プロキシとしてインスタンスで実行する方法や、バックエンドサーバーを App Engine フレキシブル環境で実行する方法があります。詳細については、VM インスタンスへの安全な接続をご覧ください。

  • 負荷分散と自動スケーリングを追加する - ロードバランサとオートスケーラーを設定して、要求が増加したときに超過インスタンスをすばやく処理し、インスタンス間で均等にトラフィックを転送することで、トラフィックの急上昇を適切に処理します。詳細については、HTTP(S) 負荷分散の設定インスタンスのグループの自動スケーリングをご覧ください。

  • REST ではなく gRPC プロトコルを使用して探索する - gRPC は、モバイルアプリがバックエンド サービスのメソッドをあたかもローカル オブジェクトであるかのように直接呼び出せるようにするフレームワークです。gRPC を使用すると、モバイルアプリの帯域幅効率を高め、GCP で実行されるバックエンド サービスとアプリの間のレイテンシを短縮できます。Stickynotes サンプルで gRPC を使用する例については、「Google Compute Engine と gRPC を使用したモバイルアプリの構築」をご覧ください。

  • バックエンド サービスに他のホスティング オプションを検討する - Compute Engine を使用すると、仮想マシンを詳細に管理できますが、その代わりに、インスタンスの更新や管理を手動で行わなければなりません。Cloud Platform でモバイル バックエンド サービスをホストするその他の方法については、Google Cloud を使用したモバイルアプリの構築をご覧ください。