目次


実行可能かつデプロイ可能な OpenWhisk 対応のコードを作成する

developerWorks サンドボックス内で実行およびデプロイできるコードを作成する方法

Comments

インタラクティブ・コード: コードのトップで実行ボタンがある場合、実行を押した後、結果を確認し再度実行してください。 デプロイボタンがある場合、コードをdeveloperWorksのBluemixアカウントにデプロイすることができます。

developerWorks サンドボックスの最大の利点としては、ブラウザー内でコードを実行することも、コードを IBM Cloud (Bluemix) にデプロイすることもできるという点が挙げられます。コードをデプロイする場合、それは OpenWhisk アクションになります。けれども OpenWhisk ではコードが特定のインターフェースをサポートすることが要件となるため、そうなっていなければコードをデプロイすることができません。このチュートリアルでは、すべてを正常に機能させるためのルールと要件を説明します。

このチュートリアルに従うことで、developerWorks サンドボックスを介してブラウザー内で実行したり、OpenWhisk アクションとしてデプロイしたりできる JavaScript または Java コードをどのようにして作成するのかがわかります。このチュートリアルでは、サンドボックスを利用して直接コードをビルド、テスト、処理することができます。各サンドボックスの後に、コードの詳細な説明が記載されています。

このチュートリアルの内容は以下のとおりです。

  1. JavaScript および Java の両方の実行可能かつデプロイ可能なコードが含まれる developerWorks サンドボックスを確認します。
  2. コードをデプロイ可能にする方法を学びます。
  3. デプロイ可能なコードを実行可能にする方法を学びます。

OpenWhisk (サーバーレス) アクションについて

簡単に言うと、OpenWhisk ではコードが JSON オブジェクトを唯一の入力として取り、出力として JSON オブジェクトを返すことを要件としています。JavaScript を使用する場合、JSON を扱うのは簡単です。一方、Java を使用する場合は、Google の gson ライブラリーを使用して JSON オブジェクトを処理する必要があります。このチュートリアルでは、JSON および gson を扱う際の詳細を説明します。コードに送信する入力 JSON オブジェクトを作成し、その JSON 出力を解釈するのは、OpenWhisk アクションを呼び出す開発者の役目であることに注意してください。

デプロイしたコードをどのようにして呼び出すのかについては、このリンク先の developerWorks チュートリアル「OpenWhisk アクションを呼び出す (日本語版2017年11月17日公開予定)」を参照してください。

実行およびデプロイできる単純なサンプル JavaScript

OpenWhisk 対応の Hello World は、実行することもデプロイすることもできる、最も単純なコードです。

このコードを実行、変更、デプロイするには、このリンク先のページからサインインしてください。

結果表示

コードをテストする

まずはコードをテストしましょう。その後、このコードを実行およびデプロイ可能にしている要素について説明します。上掲の「実行」ボタンをクリックしてください。name フィールドに渡した値に応じて、以下のような出力が表示されます。

{ greeting: 'Hello, Susan' }

次に、「デプロイ」ボタンをクリックします。サンドボックスがコードを新しいアクションとして OpenWhisk にデプロイし、新しくデプロイされたアクションの URL を表示します。

https://openwhisk.ng.bluemix.net/api/v1/web/devworkssandbox_pub/270003KAD5/0-1001.json

注: 生成される URL はそれぞれの開発者に固有のものなので、ここに記載する例とは異なります。

次は、OpenWhisk にデプロイされたコードを呼び出します。以下のサンドボックス内で、[URL] を上掲の「デプロイ」ボタンをクリックした後に生成された URL で置き換えてください (当然、必要に応じて name を変更して構いません)。以下の「実行」ボタンをクリックすると、上記のコードをデプロイしたときに作成された OpenWhisk アクションが、このサンドボックス内のコードによって呼び出されます。

結果表示

このサンドボックスの出力には見覚えがあるはずです。

{ greeting: 'Hello, Susan' }

結果は同じですが、上記の 2 つのサンドボックスの内容は大幅に異なります。最初のサンドボックス内のコードは、ブラウザー内で実行したり、OpenWhisk にデプロイしたりできるコードです。2 番目のサンドボックス内のコードは、OpenWhisk アクションを呼び出します。2 番目のサンドボックス内の url を、公開されている任意の OpenWhisk アクションの URL で置き換えて、そのアクションに必要な JSON データを追加すれば、このコードを使って目的のアクションを呼び出すことができます。

次は、実行してデプロイできるコードを実際に作成する方法の詳細を説明します。

デプロイ可能な JavaScript コードを作成する

JavaScript で作成された OpenWhisk アクションの基本的な構造は以下のようになります。

function main(params) {
  // Do something useful with the parameters here
  var output = {};
  // Put anything you want your action to return into the output object
  return output;
}

JavaScript OpenWhisk アクションを呼び出すと、OpenWhisk 環境が main() という名前のメソッドを探します。この名前のメソッドがなければ、呼び出しは失敗します。上記のサンドボックス内のコードでは、main() 関数さえあれば、コードをデプロイできます。この例の場合、name という名前のフィールドが含まれる JSON オブジェクトをコードに渡すと、すべてが正常に機能します。

JavaScript コードを実行可能にする

コードを実行可能にするには、誰かがそのコード・ファイルを実行しようとすると開始される動作を定義する必要があります。この例の場合に当てはめると、これは、デフォルトの JSON オブジェクトを作成し、そのオブジェクトを main() メソッドに渡すことを意味します。以下のコード行によって、コードが実行可能になります。

var defaultParameters = {'name': 'Susan'};
 
if (require.main === module) 
  console.log(main(defaultParameters));

「実行」ボタンがクリックされたときに使用するデフォルト・パラメーターが格納された JSON オブジェクトを定義する変数には、それにふさわしく defaultParameters という名前が付けられています。この変数宣言の後に続く行は、少々複雑です。ステートメント require.main === moduletrue に評価された場合、このファイルは require() を介して実行されるのではなく、直接実行されることを意味します。その場合、node.js ランタイムが main() メソッドを呼び出します (この手法の詳細については、Node.js のドキュメントに記載されている、main() モジュールへのアクセスに関する説明を参照してください)。

console.log() 呼び出しの中で main() メソッドを呼び出すということは、main() メソッドから返される結果はいずれも画面に出力されることを意味します。この例での単純な JSON オブジェクトは問題なく画面に出力できますが、さらに複雑なオブジェクトを使用する場合もよくあります。その場合は、JSON.stringify() メソッドを使用する必要があります。

if (require.main === module) 
  console.log(JSON.stringify(main(defaultParameters), null, 2));

JSON.stringify() メソッドは、JSON データをフォーマット化するコンビニエンス関数です。上記の例で、最初のパラメーターは main() メソッドの実際の呼び出しです。2 番目のパラメーターは null になっています (JSON データを操作する関数を渡すこともできます)。3 番目のパラメーターは、2 つのスペースを入れてデータをインデントします。有効な情報がたくさん含まれる複雑な JSON オブジェクトを返すアクションを扱う場合、JSON.stringify() によってコードをフォーマット化する手間をかけるだけの価値はあります。

もう 1 つ注意すべき点として、defaultParameters オブジェクトを宣言する必要はありません。以下のように、JSON データは main() の呼び出しの中に含めることができます。

if (require.main === module) 
  console.log(main({'name': 'Susan'}));

複雑な JSON オブジェクトを渡すとしたら、この方法は実用的ではありませんが、機能することは確かです。

非同期アクションを作成する

OpenWhisk は非同期アクションを有効にするために、JavaScript コードが基本的な JSON オブジェクトではなく、Promise を返すことを許可しています。以下の例でコードが呼び出すのは、Watson Language Translator サービスです。このサービスはストリングを取り、ソース言語とターゲット言語を指定する 2 つのコードに基づいて、そのストリングを翻訳します。

この例で、なぜ非同期アクションが必要になるのかというと、コードが Watson サービスから結果を取得する前に main() メソッドが終了しないようにするためです。Promise を返すことで、サービスから結果が返された任意の時点で、クライアントがその結果を取得できるようになります。データベース・アクセスやファイル I/O など、長時間実行されるあらゆるタスクには、この手法が役立ちます (独自の Promise を作成できるサンドボックスを含め、Promise についての詳細は、このリンク先のチュートリアルを参照してください。このチュートリアルでは、Ted Neward が ECMAScript 6 の新機能を紹介しています)。

このコードを実行、変更、デプロイするには、このリンク先のページからサインインしてください。

結果表示

デプロイ可能な非同期 JavaScript コードを作成する

非同期 OpenWhisk アクションの基本的な構造は以下のようになります。

function main(params) {
  return new Promise(function (resolve, reject) {
    invokeSomething(params, function(error, results) {
      if (error)
        reject(error);
      else
        resolve(results);
    });
  });
}

上記のサンドボックス内のコードでは、Watson Language Translator サービスの呼び出しが Promise 内で行われます。その後、何らかの時点で、サービスから Error オブジェクトと、結果を含む JSON オブジェクトが返されます。何かしら問題が発生した場合 (Error オブジェクトが null ではない場合)、reject() メソッドが Error オブジェクトを返します。問題が発生しなければ、resolve() メソッドがサービスから返された JSON オブジェクトを返します。

注: 上記のサンドボックス内のコードをこのページから呼び出す場合、コード内で使用されている usernamepassword の値を空白にできます。このコードをデプロイした後に呼び出すには、defaultParameters オブジェクトを以下のように変更する必要があります。

  1. usernamepasswordurl の各フィールドに、Language Translator サービスに対する IBM Cloud 資格情報を入力します。
  2. use_unauthenticated フィールドを false に設定します。

Language Translator サービスのインスタンスを作成して資格情報を生成する方法については、このリンク先のページに記載されている Language Translator サービスの概要を参照してください。

非同期 JavaScript コードを実行可能にする

非同期コードを実行可能にするには、Promise オブジェクトを処理する必要があるため、作業がやや複雑になります。前と同じくデフォルト・パラメーターを格納した JSON オブジェクトを定義しますが、main() メソッドを呼び出した後は、以下のように then() メソッドと catch() メソッドを使用します。

const defaultParameters = {
  'textToTranslate' : 'That that is not confusing is amazing.',
  'username'        : '',
  'password'        : '',
  'url'             : 'https://sandbox-watson-proxy.mybluemix.net/language-translator/api',
  'use_unauthenticated' : true
}

if (require.main === module)
  main(defaultParameters)
    .then((results) => console.log(JSON.stringify(results, null, 2)))
    .catch((error) => console.log(error.message));

then() メソッドは、Promise 内の resolve() 呼び出しによって返された結果を処理します。この例の場合、テキストの翻訳が含まれる JSON オブジェクトが結果として返されます。エラー・ケースに対応する catch() メソッドは、reject() から返された Error オブジェクトを処理します。

非同期アクションの詳細については、Bluemix OpenWhisk JavaScript ドキュメントにアクセスし、スクロールダウンして「非同期アクションの作成」セクションを参照してください

実行およびデプロイできるサンプル Java

次は、Java に話題を移しましょう。以下に、実行およびデプロイできる単純なサンプル・コードを記載します。

このコードを実行、変更、デプロイするには、このリンク先のページからサインインしてください。

結果表示

コードのテスト

JavaScript のサンプル・コードを使用して行ったように、コードをテストしてから、このコードを実行およびデプロイ可能にしている要素について説明します。上掲の「実行」ボタンをクリックしてください。name フィールドに渡した値に応じて、以下のような出力が表示されます。

{'greeting': 'Hello, Susan'}

次に、「デプロイ」ボタンをクリックします。サンドボックスがコードを新しいアクションとして OpenWhisk にデプロイし、デプロイされた新しいアクションの URL を表示します

https://openwhisk.ng.bluemix.net/api/v1/web/devworkssandbox_pub/270003KAD5/0-1003.json

(この場合も、URL はそれぞれの開発者に固有のものです)。

次は、OpenWhisk にデプロイされたコードを呼び出します。以下のサンドボックス内で、[URL] を上掲の「デプロイ」ボタンをクリックした後に生成された URL で置き換えてください「実行」ボタンをクリックすると、上記の Java サンドボックス内のコードをデプロイしたときに作成された OpenWhisk アクションが呼び出されます。

結果表示

このサンドボックスからの出力には見覚えがあるはずです。

{
  "greeting": "Hello, Susan"
}

デプロイ可能な Java コードを作成する

OpenWhisk では、Java クラスの基本的な構造が以下のようになっていることを要件としています。

import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

// Other imports here

public class MyClass {
  public static JsonObject main(JsonObject args) {
    // Parse the args JsonObject so we can work with it
    
    // Use the Google gson library to create a JsonObject with the 
    // appropriate output
    JsonObject returnObject = ...;
    return returnObject;
  }
}

注: developerWorks サンドボックスでは Java の package ステートメントをサポートしていないことに注意してください。

main() のシグニチャーは、これまでに使用したものとは異なります。OpenWhisk の入力および出力は JsonObject でなければならないため、上記のシグニチャーを使用する必要があります。OpenWhisk 環境には優れた Google gson ライブラリーがインストールされているので、このライブラリーを使用して JSON データを処理してください。JavaScript には JSON が組み込まれていることから、JavaScript 言語で JSON を処理するのは Java よりも簡単です。Java では、gson を介して入力および出力データを処理しなければなりません。

Java コードを実行可能にする

最初に記載した Java サンドボックス内のサンプル・コードは、デプロイすることも実行することもできます。コードを実行可能にするコード行では、デフォルト・データを作成し、従来型のシグニチャーを使用した新しい main() メソッドを作成することによって、このメソッドを多重定義します。

private static String data = "{'name': 'Susan'}";

public static void main(String[] args) {
  JsonObject jsonArgs = new JsonParser().parse(data).getAsJsonObject();
  main(jsonArgs);
}

main(String[]) メソッドは、デフォルト・データから JsonObject を作成し、main(JsonObject) メソッドを呼び出します。これだけで、コードが実行可能になります。

おまけ: 実行およびデプロイできる、より複雑なサンプル Java

おまけとして、Watson Language Translator サービスを利用する前のサンプルの Java バージョンを記載します。Watson Java SDK を使用することで、Java コレクション・クラスと各種の Java オブジェクト (TranslationResultTranslation など) を、基礎となる JSON のラッパーとして使用できます。これにより、コードの内容が通常の Java プログラムにより近いものになります。JSON データを返す段階になると、たった 1 行のコードによってサービスからの結果が JSON 構造に変換されます。

このコードを実行、変更、デプロイするには、このリンク先のページからサインインしてください。

結果表示

ご覧のように、このサンプルでは前に説明した手法を使って、コードを実行することもデプロイすることもできるようにしています。(Java は同期をとるため、Java コードのほうが node.js バージョンよりも単純になります。Java ランタイムは Language Translator サービスが結果を返すまで辛抱強く待機します。)

このコードをデプロイした後に呼び出すには、data オブジェクトを以下のように変更する必要があります。

  1. usernamepasswordendpoint の各フィールドに、Language Translator サービスに対する IBM Cloud 資格情報を入力します。
  2. kip_authentication フィールドを false に設定します。

まとめ

このチュートリアルでは、誰もが developerWorks サンドボックス内で実行、デプロイできる JavaScript コードと Java コードを作成する方法を説明しました。

IBM Cloudライト・アカウントを開いて、このチュートリアルに記載されているコードを OpenWhisk にデプロイすることをお勧めします。これは学習するのに最良の方法であり、wsk ツールと IBM Cloud コンソールに用意されている完全なデバッグ機能一式を使用できます。

サーバーレス・コンピューティングの世界をお楽しみください!


ダウンロード可能なリソース


関連トピック


コメント

コメントを登録するにはサインインあるいは登録してください。

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Web development, Open source
ArticleID=1051819
ArticleTitle=実行可能かつデプロイ可能な OpenWhisk 対応のコードを作成する
publish-date=11092017