IBM Cloud Docs
Web アプリケーションの開発

Web アプリケーションの開発

このチュートリアルでは、 IBM Cloud® Object Storageを使用して単純なイメージ・ギャラリーを作成する方法を説明します。これにより、Web 開発におけるさまざまな概念とプラクティス・キーがまとめられます。

Web アプリケーションの作成は、最初から最後まで多くの異なる概念をカバーしており、IBM Cloud Object Storage の機能を理解するのに適切な方法です。 アプリケーションは IBM Cloud Object Storage を使用して Node.js アプリケーションに保管し、ユーザーが JPEG イメージ・ファイルをアップロードして表示できるようにします。

シナリオ

このチュートリアルのシナリオには、多くの移動パーツが含まれています。

  • Web アプリケーションをホストする Web サーバー
  • コマンドラインの使用
  • ギャラリー内のイメージのストレージ・インスタンス
  • 継続的デリバリーに統合されたバージョン管理システム
  • スクリプトとマークアップの両方でのクライアント・サイド・アプリケーション・バインディング
  • アップロードして表示するイメージ

これらすべてを 1 つのパッケージで探す場合、このチュートリアルでは、完全な開始から終了までのサンプルを提供します。 ただし、この命令は、セキュリティーとセキュア・コードの原則を一時的に維持することしかできません。 実際に実稼働環境に配置される Web アプリケーションは、適切なセキュリティーを必要とします。そうしないと、訪問者の可能性には適していません。

開始前に

以下のようにして、開始する必要があるものがあることを確認します。

  • IBM Cloud プラットフォーム用のアカウント
  • IBM Cloud 開発者ツールの一部としての Docker
  • Node.js
  • Git(デスクトップとコマンドラインの両方)

コマンド行の使用

まずは、経験豊富な開発者にとっては使い慣れたツールであり、開発初心者にとっては新たな常用ツールとなるコマンド・ラインを開きましょう。 多くの場合、グラフィック・ユーザー・インターフェース (GUI) は、コンピューターのコマンド・ライン・インターフェースを第 2 クラスの状況に解放します。 しかし、現時点では、これを元に戻す必要があります (ただし、コマンド・ライン・ツール・セットの説明をダウンロードするために Web を参照する必要がある場合は、GUI はすぐには使用できません)。

シェルを開き、ディレクトリーを作成します。 自分のリファレンス・ディレクトリを、作成した新しいディレクトリに変更する。 作成されたアプリケーションは、立ち上げと実行に必要なスターターコードとコンフィギュレーションを含む独自のサブディレクトリを持ちます。

コマンド・ラインを終了してブラウザーに戻り、リンクにある IBM Cloud Platform 開発者ツール をインストールする手順に従います。 Developer Toolsは、クラウド・アプリケーションの構築とデプロイに、拡張性と再現性のあるアプローチを提供します。

Docker のインストール

Dockerなどのコンテナーを使用すると、開発が迅速化され、テストが容易になり、自動デプロイメントがサポートされます。 コンテナとは、オペレーティング・システムを必要とせず、コードと、依存関係から設定まですべてのコンフィギュレーションだけを必要とする軽量な構造だ。

Docker は、 Developer Toolsの一部としてインストールされ、必要になります。 その作業は主に、新しいアプリケーションをスキャフォールドするルーチン内のバックグラウンドで行われます。 ビルド・コマンドが機能するためには、Docker が実行中でなければなりません。 DockerhubからオンラインでDockerアカウントを作成し、Dockerアプリを実行してサインインする。

Node.js のインストール

あなたがビルドするアプリは、このWebアプリケーションのJavaScriptコードを実行するサーバー側エンジンとして Node.JSを使用しています。 NodePackage Manager (npm) を使用してアプリの依存関係を管理するには、Nodeをローカルにインストールする必要があります。 また、 Node のローカル・インストールにより、テストが簡素化され、開発が迅速化されます。

開始する前に、 Node Version Manager や nvm などのバージョン・マネージャーを使用して Nodeをインストールすることを検討してください。 バージョン・マネージャーは、さまざまなバージョンの Node.jsの管理の複雑さを軽減します。

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.34.0/install.sh | bash

...または'wget(どちらか一方だけが必要だが、両方は必要ない:)

wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.34.0/install.sh | bash

Windowsの場合は、リンク先のインストーラーとソースコードで'nvm Windows用を使うことができる。

nvm を使用して、 Nodeをインストールします。

nvm install v6.17.1

Node.js および npm ( Nodeに含まれています) をコンピューターにインストールした後でどちらの方法を使用しても、ジョブの開始をお祝いします。

Git のインストール

Gitは、最も広く使用されているソース・コード・バージョン管理システムであるため、既に熟知していると思います。 Gitを使うのは、IBM Cloudプラットフォームで継続的デプロイメント(CD)ツールチェインを作成するときです。プラットフォームで継続的デリバリーとデプロイを行う。 GitHubのアカウントをお持ちでない方は、GitHub のウェブサイトで無料の公開個人アカウントを作成してください。

コマンド・ラインから GitHub にセキュアにアクセスするには、SSH 鍵を生成して GitHub プロファイル にアップロードする必要があります。 ただし、これを行うと、後で IBM Cloud Platform に使用される GitHub のインスタンスに対してステップを繰り返すことになるため、適切な方法が用意されています。

ここでは、 GitHub Desktop をダウンロードし、インストーラーを実行します。 インストーラーが終了したら、アカウントを使用して GitHub にログインします。

リポジトリーへのコミットの名前と E メールを入力します (これはパブリックに表示されます)。 アプリケーションがアカウントにリンクされると、 GitHub アカウントを介してオンラインでアプリケーション接続を検証するように求められる場合があります。

GitHubデスクトップのログインウィンドウ
github_desktop_setup

Node.js スターター・アプリの作成

アプリケーションのローカル開発を開始するには、まずIBM Cloudプラットフォームにコマンドラインから直接ログインします。プラットフォームにコマンドラインから直接ログインします。 オプション -o を使用する組織や、オプション -s を使用するスペースなどのオプション・パラメーターを指定できます。 連携アカウントを使用している場合は、「--sso 使用する。

ibmcloud login

このチュートリアルで使用する CLI 拡張機能をダウンロードしてインストールするには、以下に示すようにコマンドを入力します。

ibmcloud cf install

ログインすると、地域を選択するように求められる場合があります。 この演習では、領域として us-south を選択します。これは、このチュートリアルの後半で CD ツールチェーンを作成するために同じオプションが使用されるためです。

次に、エンドポイントを設定します (まだ設定されていない場合)。 その他のエンドポイントも可能であり、実動での使用に適している場合があります。 ここでは、ご使用のアカウントに該当する場合は、示されているコードを使用します。

ibmcloud api cloud.ibm.com

次に、Web アプリケーションを作成します。 dev スペースは組織のデフォルト・オプションですが、さまざまな作業を分離するために他のスペースを作成することもできます。 例えば、「finance」を「development」とは別に保持します。

ibmcloud dev create

このコマンドを使用すると、一連の質問が表示されます。 プロセスの多くのポイントに戻ることができるため、失われたと感じる場合は、既存のディレクトリーを削除して新規ディレクトリーを作成することからやり直すことができます。 コマンド・ラインでアプリケーションを作成した場合でも、 IBM Cloud コンソールに結果が表示されます。

「Web アプリ」を作成するためのオプションに注意してください。 それが欲しいんだろ

===============================================================================
Select an application type:

 1. Backend Service / Web App
 2. Mobile App
-------------------------
 0. Exit

===============================================================================
? Enter selection number:> 1

いくつかのオプションが用意されていますが、「Node」が必要です。 「4」と入力し、Enter キーを押します。

===============================================================================
Select a language:

 1. Go
 2. Java - MicroProfile / Java EE
 3. Java - Spring
 4. Node
 5. Python - Django
 6. Python - Flask
 7. Swift
-------------------------
 0. Return to the previous selection

===============================================================================
? Enter selection number:> 4

プログラミング言語とフレームワークを選択すると、次の選択には非常に多くのオプションがあり、希望するサービスを超えてスクロールする可能性があります。 例に示されているように、 Express.jsで単純な Node.js Web アプリを使用したいと考えています。 「3」と入力して、Enter キーを押します。

===============================================================================
Select a Starter Kit:

APPSERVICE
-------------------------------------------------------------------------------

 1. Node-RED - A starter to run the Node-RED open-source project on
    IBM Cloud.

 2. Node.js + Cloudant - A web application with Node.js and Cloudant

 3. Node.js Express App - Start building your next Node.js Express
    app on IBM Cloud.


WATSON
-------------------------------------------------------------------------------

 4. Natural Language Understanding Node.js App - Use Watson Natural
    Language Understanding to analyze text to help you understand its
    concepts, entities, keywords, sentiment, and more.

 5. Speech to Text Node.js App - React app using the Watson Speech to
    Text service to transform voice audio into written text.

 6. Text to Speech Node.js App - React app using the Watson Text to
    Speech service to transform text into audio.

 7. Visual Recognition Node.js App - React app using the Watson
    Visual Recognition service to analyze images for scenes, objects, text,
    and other subjects.

-------------------------
 0. Return to the previous selection

===============================================================================
? Enter selection number:> 3

どこでも開発者にとって最も難しい選択肢は、アプリに名前を付けることです。 例に従って webapplication と入力し、Enter キーを押します。

? Enter a name for your application> webapplication

その後、ウェブ・コンソールを使って、データ・ストアやコンピュート・ファンクションなど、必要なサービスを必要なだけ追加することができる。 ただし、ここでサービスを追加するかどうかを尋ねられたら、「n」を入力します。 また、まだリソース・グループを設定していない場合は、この時点でプロンプトが出されることがあります。 このプロンプトで「n」を入力すると、これをスキップできます。

Using the resource group Default (default) of your account

? Do you want to select a service to add to this application? [Y/n]> n

コンテナ化されたアプリケーションを管理する1つの方法は、「デファクト Kubernetesようなオーケストレーション・ソフトウェアを使うことだ。

4」と入力してエンターキーを押すと、プロジェクトのライフサイクルにCDを統合するためにIBM DevOps'が使用される。

===============================================================================
Select from the following DevOps toolchain and target runtime environment
options:

 1. IBM DevOps, deploy to Knative-based Kubernetes containers
 2. IBM DevOps, deploy to Helm-based Kubernetes containers
 3. IBM DevOps, deploy to Helm-based Red Hat OpenShift containers
 4. No DevOps, with manual deployment

===============================================================================
? Enter selection number:> 4

自動化デプロイメント CD ツールチェーンのリージョンを選択する必要があります。 前に選択したのと同じ領域を参照するオプション「5」を選択します。

--------------------------------------------------------------------------------
Select a region for your toolchain from the following options:
--------------------------------------------------------------------------------
 1. eu-de (Frankfurt)
 2. eu-gb (London)
 3. jp-tok
 4. us-east (Washington DC)
 5. us-south (Dallas)
--------------------------------------------------------------------------------
 0. Return to the previous selection
--------------------------------------------------------------------------------
? Enter selection number:> 5

新しいアプリケーションを生成すると、アプリのデプロイに使用するツールチェーンに追加の構成が必要であることが通知されます。 前述したように、GitHub IBM Cloudプラットフォーム上のCD Toolchainインスタンス)に公開鍵をアップロードする必要があります。Platform)に公開鍵をアップロードすることが、GitHubてデプロイされたアプリケーションを配信するために必要です。

Note: For successful connection to the DevOps toolchain, this machine
must be configured for SSH access to your IBM Cloud GitLab account at
https://git.cloud.ibm.com/profile/keys in order to download the
application code.

さらにプロンプトが表示されるので、先ほど定義したアプリケーション名とツールチェーン名を確認する。 この例では、ホスト名とツールチェーン名を変更する方法を示しています。 ホスト名はアプリケーションのサービス・エンドポイントに対して固有でなければなりませんが、競合がない限り、確認を求められたら単に「戻る」を押すことができます。

The DevOps toolchain for this app will be: webapplication
? Press [Enter] to accept this, or enter a new value now>


The hostname for this app will be: webapplication
? Press [Enter] to accept this, or enter a new value now>

The app webapplication has been created in IBM Cloud.

DevOps toolchain created at
https://cloud.ibm.com/devops/toolchains/6ffb568a-e48f-4e27-aed0-00ca931dde66?env_id=ibm:yp:us-south

ibmcloud dev create コマンドによって返されたリンクをコピーして貼り付けると、CD ツールチェーンにアクセスすることもできます。 リンクをキャプチャし損ねた場合は、後でコンソールからアクセスできる。 プロセスがアプリケーション・エントリーをオンラインで作成し続けるとともに、サンプル・コードを含むディレクトリーも作成し続けると、さらに詳しい情報が続きます。

Cloning repository
https://git.cloud.ibm.com/Organization.Name/webapplication...
Cloning into 'webapplication'...
remote: Counting objects: 60, done.
remote: Compressing objects: 100% (54/54), done.
remote: Total 60 (delta 4), reused 0 (delta 0)
Receiving objects: 100% (60/60), 50.04 KiB | 1.52 MiB/s, done.
Resolving deltas: 100% (4/4), done.
OK

The app, webapplication, has been successfully saved into the
current directory.

最後の文は、カレント・ディレクトリを表示すると、新しいサブディレクトリ「webapplication」が表示されることを意味する。 このディレクトリーには、新しい Node.js アプリケーションのスキャフォールドが保持されます。 ただし、レシピが存在する可能性はありますが、それらの要素自体は Docker イメージにラップされているため、結合する必要があります。 インストールの結果、Dockerはローカル・マシンで稼働しているが、再起動が必要な場合はそうすること。 Docker を実行せずに新規 Web アプリケーションをビルドすると失敗しますが、これが唯一考えられるエラーではありません。 そのエラーメッセージには、IBM Cloudのオンラインポータルで結果ログを見るための適切なリンクがあるかもしれません。プラットフォームアカウント。

ibmcloud dev build

アプリがビルドされたので、 run コマンドを使用してコードをローカルで実行できます。 When finished, copy and paste the provided URL into your browser's address bar, typically, http://localhost:3000.

ibmcloud dev run

これで、アプリが作成され、定義されました。アプリケーションを表示して、動作することを確認してください。 図2のようなプレースホルダ画像が表示されたら、上出来だ! 新しいNode.jsウェブ・アプリケーションを作成し、クラウドにデプロイする準備ができました。

新しいNode.jsアプリケーション!
初期ノードアプリ

deploy コマンドでアプリを'IBM CloudPlatformにデプロイする(例に示すように)。

ibmcloud dev deploy

前に指定したリージョン・エンドポイントとホスト名に基づいて、 ibmcloud dev deploy によって URL が再度表示されます。 IBM Cloud Platform で、ポータルに保管されているログへのリンクを確認できます。 では、クラウド内の新しい Web アプリケーションにアクセスしてみましょう。

Web ギャラリー・アプリケーションの作成

IBM Cloud上でNode.jsアプリを開発するために必要な前提条件を思い出してみよう。プラットフォーム。 IBM Cloud プラットフォーム・アカウントを作成して、開発者ツールをインストールし、それにより Docker もインストールされました。 次に、 Node.jsをインストールします。 このチュートリアルの前提条件としてリストされている最後の項目は Gitです。これについては、ここで詳しく説明します。

ここでは、 Node.jsでのイメージ・ギャラリーでの作業の詳細について説明します。 現時点では、このシナリオでは GitHub Desktop を使用しますが、 Git コマンド・ライン・クライアントを使用して同じタスクを実行することもできます。 始めるには、新しいウェブ・アプリケーション用のスターター・テンプレートをクローンします。

以下のプロセスに従ってください。

  1. downloadからサンプルをダウンロードします。 ブラウザーを使って、アプリのテンプレートをローカル開発環境にダウンロードする。 サンプルアプリを'IBM Cloudプラットフォームからクローンするのではなく、サンプルのコマンドを使用して、'IBM Cloud Object StorageWeb Galleryアプリのスターターテンプレートを取得します。 リポジトリーが複製されると、スターター・アプリは COS-WebGalleryStart ディレクトリーに含まれています。 Git CMD ウィンドウを開き、GitHub リポジトリーを複製するディレクトリーに移動します。 そこで、このチュートリアルの最初の例に示されているコマンドを使用して、新規ファイルの追加を開始します。

    curl images/image-gallery-tutorial.zip -o image-gallery-tutorial.zip
    
  2. アプリケーションをローカルで実行します。 端末を開き、作業ディレクトリーを COS-WebGalleryStart directory に変更します。 package.json ファイルにリストされている Node.js 依存関係をメモします。 次に示すコマンドを使用して、それらを所定の場所にダウンロードします。

    npm install
    
  3. 表示されたコマンドを使ってアプリを実行する。

    npm start
    

    Open a browser and view your app on the address and port that is output to the console, http://localhost:3000.

    アプリをローカルで再起動するには、ノード・プロセスを終了(Ctrl+C)して停止させ、再度「npm start 使用する。 代わりに nodemon を使用すると、変更が検出されたときにアプリケーションが再始動されるため、時間が節約されます。 nodemon 次のようにグローバルにインストールする: npm install -g nodemon. アプリディレクトリのコマンドラインから、次のように実行してください: nodemon を使用して、アプリを起動します。

  4. アプリをデプロイメントする準備をします。 COS-WebGallery,の'manifest.yml ファイルのアプリケーション名プロパティの値を、IBM Cloudでアプリに入力した名前に更新します。必要に応じて、例に示すように、プラットフォームとその他の情報を更新します。 アプリケーションの manifest.yml は、以下の例のようになります。 アプリのルート・ディレクトリにある「package.json ファイルを、アプリの名前と作者であるあなたの名前でカスタマイズすることができます。

    applications:
    - path: .
      memory: 256M
      instances: 1
      domain: us-south.cf.appdomain.cloud
      name: webapplication
      host: webapplication
      disk_quota: 1024M
      random-route: true
    

    ここで、リモートオリジンに対話的にコードをプッシュするために、SSHキーをセットアップする必要があるかもしれない。 SSH 鍵にパスフレーズを設定した場合、リポジトリのリモートオリジンに変更をプッシュするたびに、このコードを入力する必要があります。

  5. あなたの'webapplication ディレクトリの内容を削除し、あなたが修正した'COS-WebGalleryStart ディレクトリの内容に置き換える。 ご自身のきめ細やかな Git スキルを使用して、削除されてリポジトリーに追加されたファイルを CLI または GitHub Desktop のいずれかで追加します。 次に、変更をリポジトリー・オリジンにプッシュします。 将来的には、変更をGitにプッシュするだけで、クラウドベースのウェブアプリケーションに変更を加えることができる。 CDツールチェーンは、変更をクローンしてサーバーに保存した後、自動的にサーバープロセスを再起動します。

要するに、アプリケーションを再コード化したのだから、ビルド・プロセスを繰り返せばいい。 しかし、今回は新しいイメージギャラリーのコードを使用してください。

IBM Cloud プラットフォームへのアプリのデプロイ

IBM Cloud Platform に対する変更をスターター・アプリに反映するには、前に実行したのと同じステップを繰り返して、 Developer Tools を使用してスターター・アプリをデプロイします。

  1. まだの場合、または再起動したりログアウトした場合は、IBM Cloudにログインしてください。login コマンドを使用してプラットフォームにログインします。

    ibmcloud login
    
  2. api コマンドを使用して、地域の API エンドポイントを設定します。

    ibmcloud api cloud.ibm.com
    
  3. そのアプリを配信するために、buildコマンドでアプリをビルドする(例のように)。

    ibmcloud dev build
    
    1. アプリケーションをローカルでテストしてみましょう。 これにより、 run コマンドを使用して同じコードをローカルで実行できます。
    ibmcloud dev run
    
  4. deploy コマンドを使用して、アプリを IBM Cloud Platform にデプロイします。

    ibmcloud dev deploy
    

    コードは、この例で初期ウェブ・アプリケーションのビルド、テスト、デプロイに使用される一連のコマンドを示しています。

    ibmcloud login --sso
    ibmcloud api cloud.ibm.com
    ibmcloud target --cf
    ibmcloud dev enable
    ibmcloud dev build
    ibmcloud dev run
    ibmcloud dev deploy
    

    プロセスが終了すると、 IBM Cloud プラットフォームは、アプリがアップロードされ、正常にデプロイされ、開始されたことを報告します。 また、IBM CloudPlatformウェブコンソールにもログインしている場合、アプリの状態が通知されます。Platform ウェブコンソールにもログインしている場合、アプリのステータスが通知されます。 しかし、最も重要なことは、IBM Cloud プラットフォームによって報告されたアプリの URL にブラウザーでアクセスするか、 Web コンソールから「アプリの表示」ボタンをクリックして、アプリがデプロイされたことを確認できるということです。

    アプリをテストします。 作成時にデプロイされたデフォルトのアプリ・テンプレートから、以下に示すスターター・アプリへ変化していることが見てわかれば、IBM Cloud プラットフォームへのアプリのデプロイが成功したことを示しています。

    デプロイしたアプリの表示結果。
    ''

Git ブランチの作成

ここで、IBM Cloud プラットフォーム Delivery Pipeline のビルド・ステージに使用するローカル開発環境のブランチを作成する必要があります。

  1. GitHubDesktop を使っている場合は、ブランチのアイコンをクリックします。ブランチの名前を入力するプロンプトが表示されます。 この例では「local-dev 名前として使っている。

    GitHubDesktop を使ってローカルの開発ブランチ
    ''
    を作成する。

  2. ブランチを作成すると、GitHubはLocal-dev ブランチ上のローカルファイルとデフォルトブランチ上のリポジトリにあるファイルを比較し、No local changes (ローカルの変更なし) と報告します。 これで、(図 5 に示されているように) 「Publish」をクリックして、ローカル・リポジトリーに作成したブランチを GitHub リポジトリーに追加できます。

    リポジトリのリモートオリジン
    ''
    に git ブランチを公開します。

Local-devブランチがツールチェインのGitHubリポジトリに公開されたので、IBM Cloudのビルドステージが開始されます。PlatformDelivery Pipelineは、コミットをプッシュするといつでもビルドステージに続いてデプロイステージが開始されます。 デプロイはワークフローに直接統合されているため、CLIからアプリをデプロイする必要はありません。

ストレージ認証情報の設定

Web アプリケーションの Object Storage 資格情報と、イメージの保管および取得を行う「バケット」を構成する必要があります。 The API key that you will create will need Object Storage HMAC credentials, as defined by your サービス資格. access_key_id と'secret_access_key という用語は、あなたがAWSアカウントを持っていて、すでに'aws_access_key_id と'aws_secret_access_key エントリを持つ資格情報ファイルを使用しているかもしれないので、認識するかもしれない。

API キーの作成が完了し、ダウンロードし、HMAC 資格情報をコピーしたら、以下のステップを実行します。

  1. ローカル開発環境で、資格情報を Windows パス %USERPROFILE%\\.aws\\credentials に配置します。 Mac/Linux ユーザーの場合、資格情報は ~/.aws/credentials) に移動する必要があります。 この例は典型的なクレデンシャル・ファイルの内容を示している。

    [default]
    aws_access_key_id = {access_key_id}
    aws_secret_access_key = {secret_access_key}
    
  2. の CLI コマンドを使用して作成したアプリケーションのウェブページで、IBM Cloudプラットフォームにログインします。IBM Cloudプラットフォームにログインして、開発のベストプラクティスに従って必要な認証情報を環境変数として定義します。にログインし、アプリ'webapplication を選択します。 タブの中から Runtime をクリックする。

  3. Runtimeウィンドウで、ページの最初にあるEnvironment variablesをクリックし、User-definedセクションまでスクロールすると、変数を追加することができます。

  4. ひとつは「access_key_id 値で、キーの名前は「AWS_ACCESS_KEY_ID」とし、もうひとつはシークレットアクセスキーの値で、名前は「AWS_SECRET_ACCESS_KEY する。 これらの変数とそれぞれの値は、Object Storage プラットフォームでの実行時に、アプリが IBM Cloud インスタンスに対する認証に使用するものです (図 6 を参照)。 項目の追加が終わった後に「保存」をクリックすると、IBM Cloud プラットフォームが自動的にアプリを再始動します。

    アプリ用に定義された実行環境変数
    ''

次に、サービス・インスタンスの Object Storage ポータルで、イメージを格納するバケットを追加します。 このシナリオでは、'web-images 名前のバケツを使います。

Node.js IBM Cloud Object Storage イメージ・ギャラリー Web アプリケーションのカスタマイズ

この例では MVC アーキテクチャーを使用しているため、このアーキテクチャーを反映するようにプロジェクト内のディレクトリー構造を調整することは、利便性があるだけでなく、最良の方法でもあります。 ディレクトリ構造には、EJSビューテンプレートを格納するviewsディレクトリ、expressルートを格納するroutesディレクトリ、コントローラロジックを格納する'controllers ディレクトリがあります。 これらのアイテムを、「src 名前の親ソース・ディレクトリの下に配置する(図7参照)。

アプリのソースコード構造
ディレクトリ構造

ヒント: 以前に複製したリポジトリーには、 COS-WebGalleryEnd という名前のディレクトリーが含まれています。 お好みのエディターで、完了したアプリケーションのソース・コードを表示すると、次のステップを実行する際に役立つことがあります。 これは、チュートリアルを完了したときにコミットされ、IBM Cloudプラットフォームにデプロイされる「webapplication」のバージョンです。このチュートリアルを完了すると、プラットフォームにデプロイされます。

アプリの設計

以下は、シンプルなイメージ・ギャラリー Web アプリケーションでユーザーが実行できなければならない 2 つのメインタスクです。

  • Web ブラウザーから Object Storage バケットにイメージをアップロードする。
  • Object Storage バケット内のイメージを Web ブラウザーで表示する。

次のステップでは、完全に開発された実動グレードのアプリを構築するのではなく、これら 2 つのデモンストレーション機能を完成させる方法に焦点を当てます。 このチュートリアルをデプロイし、公開した状態で実行すると、このアプリを見つけたあらゆるユーザーが、IBM Cloud Object Storage バケットにファイルをアップロードしたり、既にバケット内に存在する JPEG イメージをブラウザーで表示したりという、同じアクションを実行できることになります。

アプリの開発

package.json ファイルのスクリプト・オブジェクトの中に、"start "の定義がある。 このファイルは、アプリが開始されるたびに app.js を実行するようノードに指示するために IBM Cloud プラットフォームが使用するものです。 また、アプリをローカルでテストする際にも使用する。 app.js と呼ばれるメイン・アプリケーション・ファイルを見てほしい。 これは、'npm start コマンド(または'nodemon コマンド)でアプリを起動したときに、Node.jsに最初に処理するように指示したコードです。

{
    "scripts": {
      "start": "node app.js"
    }
}

app.js ファイルは、ノードを使用して、開始するために必要なモジュールをロードします。 Express フレームワークは、単に app という名前のシングルトンとしてアプリを作成します。 この例では、割り当てられたポートと環境プロパティ(デフォルトでは3000)でリッスンするようアプリに指示している。 起動に成功すると、コンソールにサーバーのURLとともにメッセージが表示される。

var express = require('express');
var cfenv = require('cfenv');
var bodyParser = require('body-parser');
var app = express();
//...

// start server on the specified port and binding host
var port = process.env.PORT || 3000;
app.listen(port, function() {
    console.log("To view your app, open this link in your browser: http://localhost:" + port);
});
//...

パスとビューを定義する方法について説明します。 最初のコード行は、Expressフレームワークが静的ファイルを提供するためにパブリック・ディレクトリを使用するように指示します。 それに続く行は、ビューのテンプレートが'src/views ディレクトリにあることをアプリに伝え、ビューエンジンをEJSに設定します。 さらに、このフレームワークはbody-parserミドルウェアを使用して、受信リクエストデータをJSONとしてアプリに公開する。 この例の最後の行で、expressアプリは、あなたのアプリのURLへのすべてのGETリクエストに応答し、「index.ejs ビューテンプレートをレンダリングする。

//...
// serve the files out of ./public as your main files
app.use(express.static('public'));
app.set('views', './src/views');
app.set('view engine', 'ejs');
app.use(bodyParser.json());

var title = 'COS Image Gallery Web Application';
// Serve index.ejs
app.get('/', function (req, res) {
  res.render('index', {status: '', title: title});
});

//...

以下の図は、レンダリングされてブラウザーに送信されたときのインデックス・ビュー・テンプレートを示しています。 nodemon を使用している場合は、変更を保存したときにブラウザーが最新表示されたことに気付くことがあります。

表示用のテンプレートとビューを使用して更新されたウェブアプリ
''

IBM のビュー・テンプレートは、 <head>...</head>; タグ間で HTML コードを共有するため、別個のインクルード・テンプレートに配置します。 このテンプレート(head-inc.ejs)には、1行目のページタイトルにスクリプトレット(JavaScript変数のバインディング)が含まれています。 title 変数は'app.js に設定され、その下の行でビューテンプレートのデータとして渡されます。 そうでなければ、単にCDNのアドレスを使って'Bootstrap CSS、'Bootstrap JavaScript、'JQuery を取り込んでいるだけだ。 最後に、カスタム静的 styles.css ファイルを pubic/stylesheets ディレクトリーから追加します。

<title><%=title%></title>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"
      integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u"
      crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.1.1.min.js"
        integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8="
        crossorigin="anonymous">
</script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"
        integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa"
        crossorigin="anonymous">
</script>

<link rel="stylesheet" href="stylesheets/style.css">

インデックスビューの本体には、ブートストラップスタイルのナビゲーションタブと、ブートストラップに含まれるCSSスタイルによって提供される基本的なレイアウトのアップロードフォームが含まれます。

あなたのアプリについて、この2つの仕様を考えてみよう:

  • 24行目でフォーム・メソッドを'POST に、フォーム・データのエンコーディング・タイプをmultipart/form-dataに設定する。 フォームアクションでは、フォームからアプリにデータをアプリルート"/"に送信します。 後で、そのルートへの 'POST リクエストを処理するために、ルータロジックで特別な作業をする。

  • ファイルアップロードのステータスに関するフィードバックをユーザーに表示します。 このフィードバックは "status "という変数でビューに渡され、アップロードフォームの後に表示されます。

<!DOCTYPE html>
<html>

<head>
    <%- include('head-inc'); %>
</head>

<body>
<ul class="nav nav-tabs">
    <li role="presentation" class="active"><a href="/">Home</a></li>
    <li role="presentation"><a href="/gallery">Gallery</a></li>
</ul>
<div class="container">
    <h2>Upload Image to IBM Cloud Object Storage</h2>
    <div class="row">
        <div class="col-md-12">
            <div class="container" style="margin-top: 20px;">
                <div class="row">

                    <div class="col-lg-8 col-md-8 well">

                        <p class="wellText">Upload your JPG image file here</p>

                        <form method="post" enctype="multipart/form-data" action="/">
                            <p><input class="wellText" type="file" size="100px" name="img-file" /></p>
                            <br/>
                            <p><input class="btn btn-danger" type="submit" value="Upload" /></p>
                        </form>

                        <br/>
                        <span class="notice"><%=status%></span>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>
</body>

</html>

少し時間をとって app.js に戻りましょう。 この例では、アプリへの追加リクエストを処理するためにExpressルートを設定している。 これらのルーティング・メソッドのコードは、プロジェクトの「./src/routes ディレクトリの下にある2つのファイルにあります:

  • imageUploadRoutes.js: このファイルは、ユーザーが画像を選択し、アップロードをクリックしたときの処理を行います。 このファイルは、ユーザが画像を選択し、アップロードをクリックしたときの処理を行います。

  • galleryRoutes.js: This file handles requests when the user clicks the Gallery tab to request the imageGallery view.

//...
var imageUploadRoutes = require('./src/routes/imageUploadRoutes')(title);
var galleryRouter = require('./src/routes/galleryRoutes')(title);

app.use('/gallery', galleryRouter);
app.use('/', imageUploadRoutes);

//...

イメージのアップロード

imageUploadRoutes.js のコードを参照してください。 新しいエクスプレスルーターのインスタンスを作成し、最初に「imageUploadRoutes 名前を付けなければならない。 その後、'imageUploadRoutes を返す関数を作り、'router という変数に代入する。 完成したら、この関数をモジュールとしてエクスポートし、フレームワークや'app.js のメインコードからアクセスできるようにしなければならない。 ルーティングロジックをアップロードロジックから分離するには、'galleryController.js 名前のコントローラーファイルが必要です。 このロジックは、送られてくるリクエストの処理と適切なレスポンスの提供に特化しているので、そのロジックをこの関数に入れ、'./src/controllers ディレクトリに保存する。

ExpressフレームワークのRouterのインスタンスは、HTTPの'POST メソッドが使用されたときに、ルートアプリのルート("/")へのリクエストをルーティングするように'imageUploadRoutes 設計されています。 imageUploadRoutes の'post メソッド内で、'multer と'multer-s3 モジュールのミドルウェアを使用し、'galleryController が'upload として公開している。 ミドルウェアは、アップロードフォーム'POST からデータとファイルを受け取り、それを処理し、コールバック関数を実行する。 コールバック関数で、HTTPステータスコード'200 を取得し、アップロードするリクエストオブジェクトに少なくとも1つのファイルがあったことを確認する。 これらの条件に基づいて、'status 変数にフィードバックを設定し、新しいステータスでインデックスビューテンプレートをレンダリングします。

var express = require('express');
var imageUploadRoutes = express.Router();
var status = '';

var router = function(title) {

    var galleryController =
        require('../controllers/galleryController')(title);

    imageUploadRoutes.route('/')
    	.post(
    		galleryController.upload.array('img-file', 1), function (req, res, next) {
                if (res.statusCode === 200 && req.files.length > 0) {
                    status = 'uploaded file successfully';
                }
                else {
                    status = 'upload failed';
                }
                res.render('index', {status: status, title: title});
            });

    return imageUploadRoutes;
};

module.exports = router;

それに比べ、「galleryRouter コードはシンプルさの見本だ。 imageUploadRouter で行ったのと同じパターンで、関数の最初の行で'galleryController 要求し、それからルートを設定する。 The main difference is that you are routing HTTP GET requests rather than POST, and sending all the output in the response from getGalleryImages, which is exposed by the galleryController on the last line of the example.

var express = require('express');
var galleryRouter = express.Router();

var router = function(title) {

    var galleryController =
        require('../controllers/galleryController')(title);

    galleryRouter.route('/')
        .get(galleryController.getGalleryImages);

    return galleryRouter;
};
module.exports = router;

次に、ギャラリーのコントローラーを確認します。

multer アップロードのセットアップ方法に注意してください。これにより、現時点で無視する一部のコードが切り捨てられます。 モジュール「ibm-cos-sdk、「multer、「multer-s3」が必要です。 このコードは、Object Storage サーバー・エンドポイントを指す S3 オブジェクトを構成する方法を示しています。 簡単のためにエンドポイントアドレス、リージョン、バケットなどの値を静的に設定しているが、これらは環境変数やJSON設定ファイルから簡単に参照できるかもしれない。

唯一のプロパティーとして storage を指定して新しい multer インスタンスを作成することにより、 imageUploadRouterupload を定義します。 このプロパティは、'multer に'multipart/form-data からのファイルの送信先を指示する。 IBM CloudPlatformは'S3APIの実装を使用しているので、storageを's3-multer オブジェクトに設定する。 この s3-multer オブジェクトには、 s3 オブジェクトに割り当てられた s3 プロパティーが含まれています。 myBucket 変数に割り当てられる bucket プロパティーもあります。この変数には、値 web-images が割り当てられます。 これで 's3-multer オブジェクトは、アップロードフォームからデータを受け取った際に、Object Storageバケツにファイルをアップロードするのに必要なデータを全て持つことになります。 アップロードされたオブジェクトの名前 (またはキー) は、元のファイル名です。

ファイル名の固有性を維持するために、ファイル名の一部としてタイム・スタンプを使用します。

var galleryController = function(title) {

    var aws = require('ibm-cos-sdk');
    var multer = require('multer');
    var multerS3 = require('multer-s3');

    var ep = new aws.Endpoint('s3.us-south.cloud-object-storage.appdomain.cloud');
    var s3 = new aws.S3({endpoint: ep, region: 'us-south-1'});
    var myBucket = 'web-images';

    var upload = multer({
        storage: multerS3({
            s3: s3,
            bucket: myBucket,
            acl: 'public-read',
            metadata: function (req, file, cb) {
                cb(null, {fieldName: file.fieldname});
            },
            key: function (req, file, cb) {
                console.log(file);
                cb(null, file.originalname);
            }
        })
    });

    var getGalleryImages = function (req, res) { /* ... shown below ... */ };

    return {
        getGalleryImages: getGalleryImages,
        upload: upload
    };
};

module.exports = galleryController;

ローカルでテストをする場合、console.log(file) は、ファイル・オブジェクトをコンソールに出力する便利なタスクです。 アップロードフォームのローカルテストを実行し、ファイルのコンソールログからの出力を表示します。

{ fieldname: 'img-file',
originalname: 'Chrysanthemum.jpg',
encoding: '7bit',
mimetype: 'image/jpeg' }

コールバックからのフィードバックは、テスト時にアプリケーションが「ファイルを正常にアップロード」したことを宣言します。

Success!
localtest1

イメージの取得と表示

app.js に戻って、'app.use('/gallery', galleryRouter); のコード行が、'/gallery ルートが要求されたときにそのルーターを使うようにエクスプレスフレームワークに指示していることを思い出してほしい。 そのルーターは、 galleryController.js を使用して、 getGalleryImages 関数を定義します。この関数のシグニチャーは、以前に確認したものです。 画像アップロード関数に設定したのと同じ's3 オブジェクトを使って、'listObjectsV2 という名前の関数を呼び出す。 この関数は、バケツ内の各オブジェクトを定義するインデックスデータを返します。 HTML内に画像を表示するには、'web-images バケツにあるJPEG画像をビューテンプレートに表示するための画像URLが必要です。 listObjectsV2 が返すデータオブジェクトを持つクロージャには、バケツ内の各オブジェクトに関するメタデータが含まれています。

このコードでは、".jpg "で終わるオブジェクトキーを探して'bucketContents をループし、S3の'getSignedUrl 関数に渡すパラメータを作成する。 この関数は、オブジェクトのバケット名とキーを指定すると、そのオブジェクトの署名付きURLを返す。 コールバック関数で、各URLを配列に保存し、HTTP Serverのレスポンスメソッド「res.render 値として「imageUrls プロパティに渡す。

//...

    var getGalleryImages = function (req, res) {
        var params = {Bucket: myBucket};
        var imageUrlList = [];

        s3.listObjectsV2(params, function (err, data) {
            if (data) {
                var bucketContents = data.Contents;
                for (var i = 0; i < bucketContents.length; i++) {
                    if (bucketContents[i].Key.search(/.jpg/i) > -1) {
                        var urlParams = {Bucket: myBucket, Key: bucketContents[i].Key};
                        s3.getSignedUrl('getObject', urlParams, function (err, url) {
                            imageUrlList.push(url);
                        });
                    }
                }
            }
            res.render('galleryView', {
                title: title,
                imageUrls: imageUrlList
            });
        });
    };

//...

最後のコード例は、 galleryView テンプレートの本文と、イメージを表示するために必要なコードを示しています。 res.render() メソッドから imageUrls 配列を取得し、ネストされた <div>...</div> タグのペアを反復処理します。 /gallery 経路が要求されると、それぞれがイメージに対する GET 要求を送信します。

<!DOCTYPE html>
<html>

<head>
    <%- include('head-inc'); %>
</head>

<body>
    <ul class="nav nav-tabs">
        <li role="presentation"><a href="/">Home</a></li>
        <li role="presentation" class="active"><a href="/gallery">Gallery</a></li>
    </ul>
    <div class="container">
        <h2>IBM COS Image Gallery</h2>

        <div class="row">
            <% for (var i=0; i < imageUrls.length; i++) { %>
                <div class="col-md-4">
                    <div class="thumbnail">
                            <img src="<%=imageUrls[i]%>" alt="Lights" style="width:100%">
                    </div>
                </div>
            <% } %>
        </div>
    </div>
</body>

</html>

http://localhost:3000/gallery からローカルでアプリをテストし、イメージを確認します。

バケットにアップロードされた画像が表示される
localtest2

Git へのコミット

アプリの基本機能が動作するようになったら、コードをローカル・レポにコミットし、GitHubにプッシュする。 GitHubDesktop を使って Changes をクリックし (図 11 を参照)、Summary フィールドに変更点の概要を入力して、Commit to Local-dev をクリックします。

変更は 'Git'
commit updates
でコミットする準備ができた。

「同期」 をクリックすると、コミットがリモート local-dev ブランチに送信されます。 このアクションにより、 Delivery Pipelineでビルド・ステージとデプロイ・ステージが開始されます。

CDDelivery Pipeline
''

次のステップ

最初から最後まで進み、 IBM Cloud Platform を使用して基本的な Web アプリケーション・イメージ・ギャラリーを作成しました。 この基本的な概要で説明した各概念について詳しくは、 IBM Cloud Object Storageを参照してください。

これで終了です。