目次


IBM WebSphere sMash の紹介

第 1 回: Web アプリケーションのための RESTful なサービスを作成する

強力ながらも単純なプラットフォームによる最新の手法を使ってアプリケーションを作成し、組み立て、デプロイする

Comments

コンテンツシリーズ

このコンテンツは全#シリーズのパート#です: IBM WebSphere sMash の紹介

このシリーズの続きに乞うご期待。

このコンテンツはシリーズの一部分です:IBM WebSphere sMash の紹介

このシリーズの続きに乞うご期待。

編集者からの注記: この記事が当初公開された時点では、Project Zero というインキュベーター・プロジェクトのコードをベースにしていました。当時、Project Zero という名前はコードとコミュニティーを指していましたが、現在このコードは IBM WebSphere sMash という製品として入手できるようになっています。Project Zero は現在 WebSphere sMash の開発コミュニティーとなっており、今後も引き続き、アプリケーションを開発するための無料のプラットフォームとして最新のビルド、最新のフィーチャー、そしてコミュニティーのサポートでを開発者に提供していきます。

はじめに

IBM WebSphere sMash で重点が置かれているのは、サービス指向アーキテクチャー (SOA) に準拠した Web 2.0 アプリケーションのアジャイル開発です。Web 2.0 を SOA に適用すると、Web 成果物で SOA の範囲を拡大することができます。これはつまり、RESTful な SOA だと考えてください (REST (Representational State Transfer) は 1 つのアーキテクチャー・スタイルです)。

RESTful な SOA は、HTTP (Hypertext Transfer Protocol) と基本的な RESTful な原則に重点を置いた SOA のサブセットです。RESTful なSOA では Web を成功に導いたデザイン・パターンの使用を推奨しているため、アプリケーション設計ではこのパターンに従うのが理にかなっており、そして全体的なメリットにもつながります。このメリットには、以下のものが含まれます。

  • 拡張性。これはキャッシングおよびステートレスな対話からもたらされます。
  • 単純さ。一般的に HTTP と XML、または JSON (JavaScript Object Notation) による解析とレンダリングが前提となります。
  • 共通標準による広範囲にわたる「ネットワーク効果」。例えば、サイトはコンテンツについての詳細を知らなくても Atom や RSS フィードを使用したり、集約したりすることができます。

WebSphere sMash は、代表的な Web 技術をベースにアプリケーションを作成し、組み立て、実行するための単純な環境を導入します。WebSphere sMash の環境には、Groovy および PHP のスクリプティング・ランタイムが組み込まれ、REST スタイルのサービス、統合マッシュアップ、そしてリッチ Web インターフェースを作り出すことを目的に最適化された API (Application Programming Interface) が備わっています。

WebSphere sMash には、技術的目標と社会的目標の両方があります。技術的目標は、以下の重要な 3 つの側面でアプリケーションの開発を容易にするスケーラブルなプラットフォームを提供することです。

作成
スクリプト言語 (現在は Groovy と PHP) のサポート、Restful なパターンを促進する規約、そして再利用可能なアセットのカタログによって開発を容易にすること。
組み立て
異種のサービスに迅速にアクセスし、データ・フロー、オーケストレーション、およびカスタム・メディエーションなどの統合アプリケーションに集約できるようにすること。
デプロイ
よく知られた安定性の高い Java™ 仮想マシン (JVM) をベースにしてアプリケーション中心のランタイム環境を提供し、アジャイル開発用に最適化すること (小フットプリント、高速再起動)。

社会的目標は開発プロセス自体に関係します。WebSphere sMash はコミュニティー主導型商業開発 (CD/CD) としてオープンに開発されており、WebSphere sMash の開発コミュニティーは Project Zero です。このユーザー・コミュニティーが WebSphere sMash の技術的決定を見守り、その決定に影響を及ぼします。また、ユーザーが開発チームやソース・コード自体に直接アクセスすることもできます。商用ソフトウェア開発でのこのようなレベルの透過性は IBM にとって新しい試みですが、極めて効果的なサービスの提供につながっています。

CD/CD に沿って、WebSphere sMash に関するすべての情報は projectzero.org に公開されます。この連載記事では WebSphere sMash の新たな情報を明らかにすることはありませんが、基礎となる概念を体系的に紹介していきます。

Restful なサービス

REST は、ネットワーク化したシステムを実装する上でのデザイン・パターンを表す用語です。REST は技術でも、標準でもありません。これはリソースを Web で公開するためのアーキテクチャー・スタイルです。Restful なアーキテクチャーは以下の原則に従います。

  • リクエストはクライアントとサーバー間で行われ、本質的にプル・ベースの対話形式を使用します。コンシューマーとなるコンポーネントが、サーバーから状態の表現をプルします。
  • リクエストはステートレスです。クライアントからのリクエストそれぞれに、サーバーがそのリクエストを理解するために必要なすべての情報が含まれていなければなりません。また、リクエストがサーバー側に保管されたコンテキストを利用することはできません。
  • REST は必ずしも、中間層での状態が存在しないことを意味するわけではありません。REST が意味するのは、リソースに対する要求を満たす状態は中間層での状態に依存しないということです。
  • クライアントとサーバーは同じインターフェースに従います。すべてのリソースには、Web 拡張版 SOA での汎用インターフェース、つまり HTTP とそのメソッドである GET、POST、PUT、DELETE でアクセスします。
  • クライアントは指定されたリソースにアクセスします。システムは、HTTP URL などの URL で指定されたリソースで構成されます。

REST は Web 上のサービスを表現するための重要な手法です。REST に関して理解しておかなければならない重要な点は、REST がもっとも有効に機能するのはデータをベースとしたサービスを公開する場合であるということです。こうしたデータ・サービスを組み合わせて調整することによって、新しいアプリケーションを作成することができます (これはよく、マッシュアップと呼ばれます)。以下の例に、クライアントが Restful なサービスをどのようにして確認するかを示します。

http://<host>/customer の場合:

  • GET: 顧客のリストを返します。
  • POST: Customer レコードを作成します。

http://<host>/customer/roland の場合:

  • GET: Roland の顧客レコードを返します。
  • PUT: Roland のレコードを更新します。
  • DELETE: Roland のレコードを削除します。

上記の例で公開されているリソースは Customer です。Customer は /customer という URI によって表されます。特定の顧客を表すには、/customer/ims のように Customer に ID を追加します。リソースにアクセスする目的は、HTTP ヘッダー・メソッドによって定義されます。

アプリケーション中心の設計とサーバー中心の設計について

エンタープライズでは、サーバー中心の考え方に追従するのは、プラットフォーム (Java EE ベースのサーバーなど) です。つまり、Web アプリケーションはアプリケーション・サーバー・プラットフォーム上でビルド、そしてデプロイされ、WebSphere などのサーバー・プラットフォームが Java EE 仕様で要求されるあらゆるサービス品質を実現することになります。このようなサービスの例には、キュー・ベースのメッセージング、分散トランザクション、プロトコル管理などがあります。アプリケーション・サーバーが 1 つの JVM 上で複数のアプリケーションを実行することもよくあります。アーキテクトがアプリケーションを設計する際の基本概念は、ソフトウェアおよびデータ・リソースを他のアプリケーションと共有し、アプリケーション・サーバーからサービスを (そのサービスが使用されていない場合でも) 提供するというものです。

アプリケーションが孤立したアプリケーション・サーバーにデプロイされているとしても、ほとんどの場合、利用可能なすべてのサービスを保持するのは依然としてサーバー自体です。アプリケーション・サーバーはエンタープライズ・レベルの統合を可能にするからです。エンタープライズ統合の特徴としては、各種システムにまたがる分散トランザクション、重要なデータ配信のためのキュー・ベースのメッセージングなど、さまざまなタイプのサービスがあります。エンタープライズ内のプラットフォームは各種のプロトコルとミドルウェアの管理を中心に設計され、場合によっては多数のアプリケーションに対応するエンタープライズ・データベースと通信します。

Web 2.0 の世界には、それほど重要でない類の HTTP レベルでの統合が関わってきます。通常、アプリケーション設計の中心となるのは一連のデータです。これらのデータは公開されて他のデータ・セットと組み合わせられ、データ・プロバイダーが予期しないような新しいアプリケーションを作り出すように意図されています。WebSphere sMash はアプリケーション中心の概念に従って設計されています。この概念では、アプリケーションをビルドして実行しますが、例えば WAR ファイルを別の JEE コンテナーに含めるといった、アプリケーションをパッケージ化してマルチアプリケーション・サーバーにデプロイするようなことはしません。それぞれのアプリケーションは独自のプロセス、つまり JVM 内で実行されます。

WebSphere sMash ランタイムは短時間だけ存続し、リクエストやアイドル・タイムアウトの発生後に毎回リサイクルするといったパターンをサポートするように設計されています。

WebSphere sMash はフルスタックのランタイムです。つまり、HTTP スタックを含め、アプリケーションを実行するために必要なすべてのものはプロセスに組み込まれ、外部プロキシーや Web サーバーを必要としません。ただし、外部プロキシーはクラスタリングおよびマルチアプリケーションのルーティングに使用されます。

WebSphere sMash プログラミングの中心概念

WebSphere sMash は、Web 2.0 と SOA を提携させて次世代の Web ベースのビジネス・アプリケーションをサポートするために特殊化された新しいプラットフォームの基盤です。このセクションでは、その中心概念のいくつかを説明します。中心概念をさらに詳しく調べるには、「Developer's Guide」を参照してください。

システム言語としてのスクリプトと Java

単純化された開発で主流となっているのはスクリプト言語です。WebSphere sMash では、スクリプトに関連する API を単純化することによって、サービスを開発する際のオーバーヘッド削減を支援することを目標としています。デフォルトのスクリプト言語は Groovy です。 Groovy は Java をベースとしているため、Java プログラマーはこの言語に簡単に移行することができます。WebSphere sMash は拡張モジュールという手段を使って、PHP もスクリプト言語としてサポートします。

イベント

WebSphere sMash はイベント・ベースのシステムです。システムの重要な振る舞いはすべて一連のイベントとしてアプリケーションに公開され、そこに該当するイベント状態が設定されます。アプリケーション開発者としての主な仕事は、既知のシステム・イベントに接続する一連のハンドラーを提供し、目的とするアプリケーションの振る舞いを実現することです。標準イベントは、アプリケーションにとって興味深い重要なアクティビティーです。

例えばシステムを介した HTTP リクエストは一連のイベントを発生させますが、開発者はそのそれぞれに対してハンドラーを作成することができます。この概念を説明しているのが図 1 です。この図には、セキュリティーに関する処理をするためのイベントや、特定の HTTP メソッド (GET や POST) のイベントなどをハンドラーが処理している様子が示されています。イベント処理についての詳細は、「Developer's Guide」のイベント処理に関するセクションを参照してください。

図 1. イベント
イベント
イベント

イベント・ハンドラーを作成するには、図 2 の例に示すように様々な方法があります。Groovy や PHP などのスクリプト言語を使用する場合には、必ずしもハンドラーを登録する必要はありません。WebSphere sMash に用意されているさまざまな規約により、構成が少なくなったり、あるいは不要になったりするためです。特定のディレクトリーにスクリプトを配置すると、WebSphere sMash がそのスクリプトを自動的にハンドラーとして登録します。

例えば図 2 のスクリプトは、Web サービス・ルートとして機能する public というディレクトリーに配置されます。スクリプト・ファイルの名前が hello.groovy だとすると、ユーザーは http://<host>/hello.groovy に対して HTTP GET を実行することができます。すると GET イベントが出力されて、ハンドラー onGET が呼び出されます。この図に示している最初のスクリプトはイベント・ハンドラーのメソッドに配置されないことに注意してください。このスクリプトは public ディレクトリーに置かれるため、WebSphere sMash はあらゆる HTTP メソッドへの応答としてこのスクリプトを呼び出します。規約については、後で説明します。

Figure 2. Event handler examples
Figure 2. Event handler examples
Figure 2. Event handler examples

グローバル・コンテキスト

WebSphere sMash のイベント・ハンドラーには、明示的な入力パラメーター (リクエストなど) と出力パラメーター (レスポンスなど) がありません。WebSphere sMash のイベント・ハンドラーはステートレスで、イベント・ハンドラーが呼び出されてから次に呼び出されるまでの間に変化する状態を維持することができないため、WebSphere sMash ではすべての状態にアクセスしてその状態を維持する手段としてグローバル・コンテキストを用意しています。グローバル・コンテキストは、現行イベントに関するすべての重要なデータをアプリケーションに提供するとともに、アプリケーションを構成するコンポーネントが情報を保管し、共有するためのメカニズムとなります。

グローバル・コンテキストにはスコープがあり、一連のゾーンに分割されています。それぞれのゾーンが維持するデータの可視性とライフ・サイクルは異なります (図 3 を参照)。例えば、ユーザー・ゾーンには特定クライアントのセッション状態が含まれます。このゾーンは該当するクライアントにだけ可視で、データはユーザーがアクティブでなくなるまで維持されます。

リクエスト・ゾーンに含まれるのは現在アクティブなリクエストの状態です。このゾーンはそのリクエストに対して実行されるコンポーネントにのみ可視で、ここに含まれる状態はリクエストの処理が完了するまで維持されます。

図 3. グローバル・コンテキスト
グローバル・コンテキスト
グローバル・コンテキスト

WebSphere sMash には 7 つのゾーンがあります。そのうち、いくつかのゾーンは永続的ではありません (表 1 に記載)。これらの非永続ゾーンはメモリー内にだけ存在し、再起動によって失われます。

表 1. 非永続ゾーン
ゾーン説明
構成 (config)/config ゾーンのデータは構成ファイルからロードされます。このゾーンのデータはグローバルに可視なデータで、アプリケーションの存続期間中、維持されます。構成ゾーンは変更できますが、JVM の再起動時にコンテンツが構成ファイルから再初期化されると、行った変更は失われます。
リクエスト (request)/request ゾーンのデータは、HTTP リクエストを処理するスレッドに対して可視になります。リクエスト・ゾーンは、リクエストがシステムに入り、レスポンスが送信されるまで維持されます。

サーブレット・プログラミングでお馴染みかもしれませんが、リクエスト・ゾーンには HttpServletRequest および HttpServletResponse によって提供される機能が統合されています。このゾーンから、着信データ、リクエスト・パラメーター、ヘッダー、cookie、POST 本文、入力ストリーム、発信データ、発信ヘッダー、発信 cookie、そして出力ストリームにアクセスできます。

イベント (event)/event ゾーンのデータは、イベントを処理するスレッドに対し、そのイベントの処理期間中、可視になります。WebSphere sMash は、疎結合コンポーネントがこれらのイベントをパブリッシュおよびサブスクライブすることを可能にするイベント処理フレームワークとなります。

イベントが複数のイベント・ハンドラーに配信された場合、そのすべてのイベント・ハンドラーが、イベント・ゾーンから元のイベント・データにアクセスすることができます。

一時 (tmp)/tmp ゾーンのデータはグローバルなデータで、アプリケーションのすべてのスレッドから確認することができます。このゾーンには、アプリケーションがあらゆるオブジェクトを保管するために使用できるスクラッチ・パッド・エリアがあります。

一方、永続ゾーン (表 2 に記載) のデータは、JVM が再起動しても存続されます。

表 2. 永続ゾーン
ゾーン説明
ユーザー (user)/user ゾーンのデータは、HTTP セッションのすべてのスレッドから確認することができます。HTTP セッションを識別するのは、リクエストで検出された zsessionid cookie の値です。ユーザー・ゾーンはサーバー・リサイクルが行われても維持されます。このゾーンのコンテンツは、Java によるシリアライズによってシリアライズされます。そのため、ここにはシリアライズ可能なオブジェクトだけが配置されます。

HTTP セッションは、一定期間アクティブでないとタイムアウトになります。このアイドル・タイムアウトは、zero.config にある /config/userZoneIdleTimeout の値によって設定されています。zsessionid cookie の有効期限が切れた場合にもセッションはタイムアウトとなって無効になります。

アプリケーション (app)/app ゾーンのデータはグローバルなデータで、アプリケーションのすべてのスレッドから確認することができます。このゾーンには、アプリケーションがシリアライズ可能なあらゆるオブジェクトを保管するために使用できるスクラッチ・パッド・エリアがあります。このゾーンはサーバー・リサイクルが行われても存続されます。
ストレージ (storage)/storage ゾーンのデータはグローバルなデータで、アプリケーションのすべてのスレッドから確認することができます。このゾーンには、JSON 型 (List、Map、String、Double、Long、Boolean、および null) としてシリアライズされたデータを保管する際にアプリケーションが使用できるスクラッチ・パッド・エリアがあります。このゾーンはサーバー・リサイクルおよび再起動が行われても存続されます。

グローバル・コンテキストは、アプリケーションのどの部分からでも使用することができます。アクセス手段は、使用している言語によって異なります。アクセスの特性を定義するのは GlobalContext への Java API です。この API のバインディングは、Groovy および PHP によって行われます。例えば request 変数はリクエスト・ゾーンにバインドされるため、リクエスト・ゾーンの myData にはドット表記 (request.myData) を使用してアクセスすることができます。グローバル・コンテキストは、キーと値のペアによってアクセスするマップのようなものです。グローバル・テキストに対しては、さまざまなキーの取得、入力、表示、削除を行うことができます。図 4 に、イベント・ハンドラーが GlobalContext にアクセスする例を示します。

図 4. グローバル・コンテキストへのアクセス
グローバル・コンテキストへのアクセス
グローバル・コンテキストへのアクセス

グローバル・コンテキストは値のパス指定、つまり特定のオブジェクト・タイプへの直接アクセスをサポートします。例えばリスト要素には、zget("/request/myList#3") を使用してアクセスすることも、zget("/request/myMap#key") を使用してマップに含まれるキーの値でアクセスすることもできます。

規約およびアプリケーションのディレクトリー構造

WebSphere sMash 環境にはいくつかの規約があり、これらの規約に従うことで、WebSphere sMash アプリケーションの開発は大幅に単純化され、指定しなければならない構成情報も最小限になります。WebSphere sMash がその目標の 1 つとしているのは、構成情報をできるだけ少なくすることです。一部の規約は一般的なもので、例えばアプリケーションのスクリプトを public フォルダーに配置すると、そのスクリプトは構成データがなくても HTTP リソースに応じて実行することができます。図 5 には、GET イベントにイベント・ハンドラー・メソッドを使用するhello.groovy というスクリプトの例が示されています。このスクリプトは、http://<application_host>/hello.groovy に対して GET が呼び出されると実行されます。

図 5. public ディレクトリー
public ディレクトリー
public ディレクトリー

その他の規約については特定のパターンに合わせて調整されています。図 6 は、incentive.groovy という名前の Groovy スクリプトを特定のフォルダーに配置する例です。この手法では、その特定フォルダー内のメソッドは、HTTP REST イベントに応答するように自動的に登録されます。この RESTful なパターンを使ってデータを公開する RESTful なサービスを簡単に開発する方法をこのあと説明します。

図 6. RESTful なリソースの仮想ディレクトリー
RESTful なリソースの仮想ディレクトリー
RESTful なリソースの仮想ディレクトリー

サンプルを作成する手順のなかで、さまざまな仮想ディレクトリーとアプリケーション・ディレクトリーについて説明します。詳細は、「Developer's Guide」の「Virtualized directories」セクションを参照してください。

サンプル・シナリオ

WebSphere sMash で初めての RESTful なサービスを作成する準備はほとんどできていますが、まずはこのセクションで、シナリオの概要を説明します。このシナリオは、連載を通して使用します。

要件

この連載では全体を通して共通のサンプルを使用し、これをベースとしてさまざまな概念を学んでいきます。シナリオのテーマはエネルギーです。利用者が求めるのはエネルギー費の節約なので、エネルギーのプロバイダー (Energy provider) は特定のエネルギー・パターンに基づいたインセンティブ (incentives) による割り戻し (rebates) を提供しています。エネルギーの利用者 (Energy consumer) は世帯主、企業、あるいはその他のエンティティーの場合があります。例えば、ある世界的企業では、自分たちが対象資格を持つエネルギー・インセンティブを検索できる高速な状況依存型アプリケーションの作成を考えているとします。この企業では、世界中に点在するデータ・センターに適用可能なエネルギー・インセンティブをインターネットで検索できる Web アプリケーションを作成しようとしています。

利用者がインセンティブを検索するには、エネルギーのプロバイダーがインセンティブ・データをインターネットで提供できるようにしなければなりません。ここで鍵となるのが、RESTful な SOA です。コンテンツを RESTful な方法で公開することができれば、他の人々がそのデータを利用して新しいアプリケーションを作成することができます。図 7 に、このシステムのユース・ケース図を示します。

図 7. サンプルのユース・ケース
サンプルのユース・ケース
サンプルのユース・ケース

この記事で読者に演じてもらう役割は、NJEnergy という名前のエネルギー・プロバイダーであり、WebSphere sMash を使用してインセンティブ・データを公開、管理することになります。

データ・モデル

NJEnergy では 1 つのデータベース・テーブルにインセンティブ・データを保管しています (図 8 を参照)。

図 8. Incentive テーブル
Incentive テーブル

目標は、このデータを公開する WebSphere sMash アプリケーションを作成することです。

RESTful なサービスの設計

データ・セットの概要は以上のとおりです。次はデータを RESTful な名前空間にマッピングする作業に取り掛かります。通常、特定のエンティティーをリソースにマッピングするためのテーブルを作成しておくと大いに役立ちます。表 3 は、サンプルのリソースの RESTful なマッピング例で、これを基に RESTful なサービスを作成していきます。

表 3. インセンティブの REST エンドポイント
リソースURIメソッド表現形式説明
インセンティブ・リスト /incentive GET JSON オブジェクトの配列と Atom フィードの双方 インセンティブのリストを取得する
インセンティブ /incentive POST JSON オブジェクト インセンティブを新規に作成する
インセンティブ /incentive/<incentiveId> GET JSON オブジェクト 個々のインセンティブを取得する
インセンティブ /incentive/<incentiveId> PUT JSON オブジェクト 単一のインセンティブを更新する
インセンティブ /incentive/<incentiveId> DELETE 単一のインセンティブを削除する

データの表現形式として JSON を選んだ理由は、リッチ・インターネット・アプリケーション (RIA) をシステムへのフロント・エンドとして使用するためです。インセンティブのリストには、Atom フィードも提供します。ブラウザーでの Ajax では JavaScript を主要なプログラミング言語としているため、ほとんどの Ajax ベースのツールキットは JSON に十分対応可能です (JSON についての詳細は、「参考文献」を参照してください)。

RESTful なサービスのセキュリティー

サービスを定義すると、続いてサービス品質をサービスに関連付けられるようになります。非機能要件は、形もサイズもさまざまです (非機能要件に対する適切で実際的な対処法については、記事「Why do non-functional requirements matter?」を参照してください)。ここでは REST を使って HTTP ベースのサービスを提供しているため、非機能要件の適用は簡易化することができます。

このサンプル・アプリケーションではセキュリティーに対処するため、URL をセキュアにすることによって REST リソースにセキュリティー・ルールを適用します。表 4 は、セキュリティーに重点を置いた REST の例を示す表です。

表 4. セキュリティー
リソースURIメソッドロールインスタンス・レベルでのセキュリティーの必要性
インセンティブ /incentive POST 管理者 あり。各プロバイダーが管理できるのは所有するインセンティブのみ
インセンティブ /incentive GET すべて なし
インセンティブ /incentive/<incentiveId> GET すべて なし
インセンティブ /incentive/<incentiveId> PUT 管理者 あり。各プロバイダーが管理できるのは所有するインセンティブのみ
インセンティブ /incentive/<incentiveId> DELETE 管理者 あり。各プロバイダーが管理できるのは所有するインセンティブのみ
インセンティブ /incentive?location=<input> GET すべて なし
その他のリソース /<Anything Else> すべて 該当ロールなし

前提条件

この記事のサンプルを実行するには、以下のものが必要です。

WebSphere sMash を使用して初めて作成する RESTful なサービス

このセクションでは、アプリケーション・ビルダーの起動手順を説明した後、いくつかの成果物について検討します。その上で、依存関係を追加し、データベースの構成エントリーを作成します。

アプリケーション・ビルダーを起動してアプリケーションを作成する

この記事の前のバージョンでは、Project Zero 用の Eclipse プラグインを使用しました。今回のバージョンでは、WebSphere sMash 対応の Web ベースのアプリケーション・ビルダー (AppBuilder) を使います。

  1. AppBuilder を起動するには、コマンド・プロンプトに移動してコマンドを実行します。
    1. AppBuilder はターミナル・ウィンドウ (例えば MAC の場合は iTerm、Windows の場合は CMD プロンプト) から起動することができます。zero を解凍したディレクトリーに移動して、コマンド appbuilder open (あるいは ./appbuilder open) を実行します。図 9 の例で使用しているのは、MAC の iTerm です。

      初めて AppBuilder を実行する場合、WebSphere sMash ランタイムが、AppBuilder を実行するために必要なコンポーネントを projectzero.org からダウンロードし始めます。このダウンロードは、AppBuilder を最初に実行するときにだけ行われます。

      図 9. ターミナル・ウィンドウ
      ターミナル・ウィンドウ
      ターミナル・ウィンドウ
    2. コマンドの実行が完了すると Firefox が自動的に開き、http://localhost:8070 にアクセスします。これは AppBuilder のローケーションで、AppBuilder 自体が 1 つの WebSphere sMash アプリケーションとなっています。図 10 に、Firefox 内で起動した AppBuilder を示します。
      図 10. AppBuilder
      AppBuilder
      AppBuilder
  2. AppBuilder が起動したので、新しいアプリケーションの作成に取り掛かります。
    1. New Application を選択し (図 11 を参照)、新しいアプリケーションの名前として NJEnergy と入力します。デフォルトのルート・ディレクトリーは変更せずに、モジュール・グループに stable が指定されていることを確認します。オプションで、説明を入力することもできます。最後に Create を選択してください。
      図 11. 新規アプリケーション NJEnergy の作成
      新規アプリケーション NJEnergy の作成
      新規アプリケーション NJEnergy の作成
    2. 以下に示すように、NJEnergy が表示されるので、NJEnergy をクリックします。
      図 12. NJEnergy アプリケーション
      NJEnergy アプリケーション
      NJEnergy アプリケーション

アプリケーション成果物

アプリケーションを作成する前に、いくつかのアプリケーション成果物について説明しておきます。AppBuilder の Explorer ビューを表示すると、アプリケーションのディレクトリーとファイルを確認することができます。

図 13 は、アプリケーションのレイアウトと、フォルダーについての説明です。このように、アプリケーションには複数のディレクトリーがあります。app フォルダーには複数のサブフォルダーがあり、開発者はこれらのサブフォルダーにスクリプトを保管します。WebSphere sMash はサブディレクトリーに応じて、いくつかの規約を適用します。例えば /app/resources ディレクトリーは、この記事でこれから行うように、RESTful サービスをスクリプトから作成する際に使用します。config ディレクトリーにはいくつかの構成ファイルが含まれます。

図 13. アプリケーションのレイアウト
アプリケーションのレイアウト
アプリケーションのレイアウト

依存関係

まずは、アプリケーションに依存関係を追加してください。WebSphere sMash は Apache Ivy の技術を使用します。依存関係を維持するのは、config ディレクトリーに保管されている ivy.xml ファイルです。このファイルを手作業で編集することもできますが、この例では AppBuilder の依存関係ページを使用します。

WebSphere sMash は Ivy によってリポジトリーの概念を適用します。リポジトリーには、ローカル・リポジトリーとリモート・リポジトリーがあります。WebSphere sMash アプリケーションは一連の依存関係を宣言し、ランタイムが Ivy 技術を使用してローカル・リポジトリーに依存関係があるかどうかを調べます。存在しない場合は、その依存関係をリモート・リポジトリーからダウンロードします。デフォルトでは、リモート・リポジトリーは projectzero.org にあります。ただし、これとは異なるリモート・リポジトリーを構成しても構いません。初めて AppBuilder を実行するときには sMash ランタイムが必要な依存関係をダウンロードしますが、Ivy ではバージョンに基づくダウンロードもサポートします。例えば 1.0.0.0, 2.0.0.0 と指定すると、WebSphere sMash は1.0.0.0 以降で、2.0.0.0 より前の最新のバージョンを取得します。

AppBuilder には、ローカル・リポジトリーまたはリモート・リポジトリーから依存関係を追加するためのツールが用意されています。

  1. Dependencies を選択すると、アプリケーションの依存関係の一覧を示すボックスが表示されます。このボックスには、ivy.xml で維持されている依存関係が直接読み込まれます。Add を選択してください。
    図 14. 依存関係
    依存関係
    依存関係
  2. zero.data と入力します。Filter byには必ず Latest major version を指定した上で、zero.data パッケージを選択してください。
    図 15. 依存関係の追加
    依存関係の追加
    依存関係の追加
  3. 同じようにして、さらに以下の 2 つの依存関係を追加します。
    1. zero.atom (Atom フィードを作成するためのsMash ライブラリー)
    2. derby (組み込みバージョンの Apache Derby データベースに接続するためのドライバー)

    追加し終わった時点で、依存関係は図 16 のようになっているはずです。

    図 16. 依存関係の追加
    依存関係の追加
    依存関係の追加
  4. Explorer タブに戻り、config ディレクトリーの下にある ivy.xml ファイルを開きます。この XML ファイルの <dependencies> セクションに、すべての依存関係が記載されます。
    図 17. ivy.xml
    ivy.xml
    ivy.xml

構成

WebSphere sMash の目標は、規約に依存することによって、アプリケーションを作成する際に必要となる構成の量を減らすことです。ただし、データベースやセキュリティー・ルールなどについては構成する必要が出てくる場合があります。このセクションでは、データベースの構成エントリーを作成します。

WebSphere sMash での構成作業は、zero.config ファイルで行います。前に説明したように、すべてのデータは複数のゾーンからなるグローバル・コンテキストに保管されます。グローバル・コンテキストのゾーンのうち、構成データを作成するのは config ゾーンです。このセクションでは、データベースの構成スタンザを作成します。WebSphere sMash アプリケーションの構成は、zero.config ファイルに含まれています。

  1. File Editor タブを選択します。All Files の下にある zero.config ファイルを探して選択してください。
    図 18. zero.config
    zero.config
    zero.config
  2. zero.config ファイルに、以下に示す構成テキストを追加します (このテキストは、ダウンロード・ファイルに含まれる <download_root>/sMashArticleSeries/Part1/dbconfig.txt からペーストすることができます)。
    図 19. データベースの構成
    データベースの構成
    データベースの構成

次に、データベース・テーブルとサンプル・データを作成する必要があります。WebSphere sMash の目標の 1 つは、アプリケーションを簡単に作成できるようにすることです。そのための 1 つの方法として使用できるのが、zero コマンドライン・インターフェース (CLI) です。このコマンドライン・ツールは sMash 開発全体で使用することができます。また、アプリケーションの実行、アプリケーションの管理、 Ivy リポジトリーの管理を行うこともできます。WebSphere sMash AppBuilder にはコマンドを入力できる Console ビューがあり、ここに zero <task> <options> の形式でコマンドを入力します。

WebSphere sMash にはデータベース・スクリプトを実行するためのタスクが用意されています。以下の手順では、zero コマンドラインを使用してデータベース・スクリプトを実行します。

  1. File Editor 内の Recent Files で、New File -> Other を選択します。
    図 20. ファイルの新規作成
    ファイルの新規作成
    ファイルの新規作成
  2. 以下のように、新しいファイルに /sql/dbscript.sql という名前を指定します。
    図 21. dbscript.sql
    dbscript.sql
    dbscript.sql
  3. 図 22 に示す SQL テキストを追加します (このテキストは、ダウンロード・ファイルに含まれている <download_root>/sMashArticle/Part1/dbscript.txt からペーストすることができます)。
    図 22. SQL スクリプト
    SQL スクリプト
    SQL スクリプト

次のステップは、AppBuilder の Console ビューを表示して、データベース・スクリプトを実行するための zero タスクを実行することです。

  1. Console タブを選択し、このタブで Command Prompt を選択します。
    図 23. コマンド・プロンプト
    コマンド・プロンプト
    コマンド・プロンプト
  2. コマンド zero runsql NJDB sql/dbscript.sql を入力します。この runsql コマンドが取るのは、zero.config に構成したデータベース名と、スクリプト名です。
    図 24. runsql コマンド
    runsql コマンド
    runsql コマンド
  3. 以下のような結果が表示されるはずです。
    図 25. コマンドの実行結果
    コマンドの実行結果
    コマンドの実行結果

RESTful なリソースの作成

この時点で、Groovy スクリプトを作成して、そのスクリプトを /app/resources ディレクトリー内に配置することによって、RESTful なリソースを作成することができます。前に、WebSphere sMash はイベントをベースとするので、開発者の仕事はイベント・ハンドラーを作成することであると説明しました。その説明のなかで、onGET や onPOST などのイベント・ハンドラーを使用する Groovy スクリプトを public ディレクトリーに配置する例を紹介しましたが、専用の仮想ディレクトリーを使ってデフォルトの振る舞いを可能にするという概念も思い出してください。

このセクションでは /app/resources ディレクトリーを使用します。/app/resources ディレクトリーは REST サービスのリソースを作成するための専用ディレクトリーです。表 5 に、URI パターンと HTTP メソッド、そして出力されるイベントを記載します。URI パターンはインセンティブなどのコレクション用です。もっとも一般的に使用されるパターンについては太字で強調表示しています。

表 5. sMash の REST イベント
URI パターンHTTP メソッドsMash イベント説明
/resources/collectionGETlistすべてのメンバーを一覧にする
POSTcreateメンバーを作成する
PUT putCollection コレクションを更新する
DELETE deleteCollection コレクションを削除する
/resources/collection/{id}GETretrieve1 つのメンバーを取得する
PUTupdateメンバーを置換する
DELETEdeleteメンバーを削除する
POST postMember メンバーを更新する

URI 内のコレクション名がインセンティブの場合 (http:<host>/resources/incentive)、incentive.<script-ext> (incentive.groovy、incentive.php など) という名前のスクリプトでハンドラーが検索されます。つまり、/resources/incentive からの GET リクエストでは list イベントが出力され、sMash は incentive.groovy または incentive.php 内で onList() ハンドラーを探すことになります。GET リクエストが例えば /resources/incentive/3 のようにメンバー・レベルで行われたとすると、incentive.groovy または incentive.php 内で onRetrieve() ハンドラーを探すことになります。メンバー・レベルでは、sMash は自動的に GlobalContext に ID を入力し、この ID の後に任意の pathInfo を追加で続けます。

sMash は /provider/<providerId>/incentive/<incentiveId> のようにネストされたリソースもサポートします。ネスト関係を指定するには、特殊な incentive.bnd ファイルを作成します。表 6 に、リソース・リクエスト、ハンドラー情報、そして渡されるイベント・データの例を記載します。

表 6. イベントの処理およびイベント・データ
HTTP メソッド適用対象 URIapp/resources/incentive.groovy 内で呼び出されるメソッド使用されるイベント・データ
GET /resources/incentive onList
POST /resources/incentive onCreate zget(“/request/input”) // POST data
GET /resources/incentive/3 onRetrieve zget("/request/params/incentiveId")==3
DELETE /resources/incentive/3 onDelete zget("/request/params/incentiveId")==3
PUT /resources/incentive/3 onUpdate zget("/request/params/incentiveId")==3

上記の 5 つのリソース・イベントに応答するインセンティブ・サービスを作成するには、まず RESTful なリソースを作成する必要があります。

  1. File Editor に戻り、以下のように New File -> New Resource in (/app/resources) の順に選択します。
    図 26. 新規リソース
    新規リソース
    新規リソース
  2. /app/resources の後に incentive.groovy を追加します。
    図 27. incentive.groovy
    incentive.groovy
    incentive.groovy

次に必要な作業は、list イベントに応答するイベント・ハンドラーの作成です。クライアントが /incentive で HTTP GET を実行すると、このイベント・ハンドラーが実行されることになります。

図 28 に示すコードを追加してください (このコードは、ダウンロード・ファイルに含まれる <download_root>/sMashArticleSeries/Part1/onList.txt からペーストすることができます)。このコードでは、zero.data API を使ってマネージャー (zero.config に構成) にアクセスし、このマネージャーが zero.data API を使用して SQL 文を実行するようにしています。クエリーの結果は、JSON としてレンダリングされます。これは、sMash に事前定義されたレンダラーです。カスタム・レンダラーが必要な場合は、テンプレートを /app/views に保管して、テンプレートを実装するスクリプトの名前を渡してください。

図 28. onList
onList
onList

この時点で簡単にアプリケーションを実行してテストすることができます。

  1. 右上隅にある Run をクリックします (図 29 を参照)。
    図 29. アプリケーションの実行
    アプリケーションの実行
    アプリケーションの実行
  2. アプリケーションが起動するまで待ちます。AppBuilder が適切な zero コマンドを実行してアプリケーションを起動する間、Starting the application アイコンが表示されます。
    図 30. アプリケーションの起動
    アプリケーションの起動
  3. Stop ボタンの隣にあるアプリケーションのリンクをクリックします。
    図 31. アプリケーションの表示
    アプリケーションの表示
    アプリケーションの表示
  4. 新しいブラウザーのタブまたはページに、実行中のアプリケーションが表示されます。最初に表示されるのは、デフォルトの index ページです (図 32 を参照)。作成した RESTful なサービスをテストするには、Firefox Poster プラグインを使用します。P アイコンを選択して Poster を立ち上げてください。
    図 32. デフォルト index ページ
    デフォルト index ページ
    デフォルト index ページ

Firefox Poster は Firefox の便利な拡張機能で、POST、PUT、DELETE などの実行を含め、RESTful なサービスをテストすることができます。このツールを使って、RESTful なやりとりをテストします。

  1. 以下のように URL に http://localhost:8080/resources/incentive と入力し、GET を選択します。
    図 33. Poster による GET
    Poster による GET
    Poster による GET
  2. すると、インセンティブの JSON リストが表示されます。
    図 34. /resources/incentive の結果
    /resources/incentive の結果
    /resources/incentive の結果

インセンティブのリストを取得するための RESTful なリソースを作成したところで、次は retrieve イベントのハンドラーを作成します。このハンドラーは、URI パターンに基づく単一のインセンティブを返します。

  1. 図 35 に onRetrieve ハンドラーを示します (このコードは、ダウンロード・ファイルに含まれている <download_root>/sMashArticleSeries/Part1/onRetrieve.txt からペーストすることができます)。クエリー・ストリング内には、グローバル・コンテキストにアクセスする GString 変数があります。リクエスト・ゾーンには前にも示したように ID が保管されます (内部ではあらかじめ準備された文を zero.data API が使用します)。
    図 35. onRetrieve
    onRetrieve
    onRetrieve
  2. これで Firefox Poster ツールに戻って URI をテストすることができます。http://localhost:8080/resources/incentive/1 と入力して GET を選択してください。
    図 36. onRetrieve のテスト
    onRetrieve のテスト
    onRetrieve のテスト
  3. すると、図 37 の結果が表示されるはずです。
    図 37. onRetrieve の結果
    onRetrieve の結果
    onRetrieve の結果

ここまでのところは JSON データを返しただけでしたが、Web 2.0 アプリケーションでは Atom フィードを返さなければならない場合もあります。そこで、onList メソッドを更新して Atom フィードを返すようにします。さらに、リストのサブセットも用意することにします。

  1. onList 実装を、図 38 に示すコードに置き換えます (このコードは、ダウンロード・ファイルに含まれている <download_root>/sMashArticleSeries/Part1/onListAtom.txt からペーストすることができます)。以下の点に注意してください。
    • 最初に、GlobalContext を使用しているクエリー・パラメーターを探します。リスト要素には直接アクセスすることができます。
    • クエリーを実行した後、コードはフォーマット要素のリクエスト・パラメーターをチェックします。パラメーターがある場合は、その値が atom であるかどうかを確認し、これに該当する場合には Groovy スクリプトを使用して要求された Atom フィールドを持つ構造を生成し、レンダリングします。
    図 38. Atom または JSON を返す onList
    図 38. Atom または JSON を返す onList
    図 38. Atom または JSON を返す onList
  2. Firefox ブラウザーを表示して、今度は別のタブに http://localhost:8080/resources/incentive?format=atom と入力します (図 39 を参照)。
    図 39. Atom の結果
    Atom の結果
    Atom の結果

これで、読み取り用の GET メソッドのコードは完成しました。次は、POST、PUT、DELETE メソッドのコードを作成します。

  1. 図 40 に示すコードを追加します。これは、<root>/freeからペーストすることができます (このコードは、ダウンロード・ファイルに含まれる <download_root>/sMashArticleSeries/Part1/onList.txt からもペーストすることができます)。このコードでは、以下の点に注意してください。
    • 以前記載したように、HTTP の POST、PUT、DELETE メソッドにそれぞれ対応する作成、更新、削除のメソッド・ハンドラーがあります。
    • WebSphere sMash には、JSON のデコード・メソッドおよびエンコード・メソッドがあります。GlobalContext の request.input[] 変数をデコード・メソッドに渡すことで、簡単に入力のスクリプト表現 (JSON オブジェクトのGroovy Map、または配列の Groovy List) を取得することができます。
    • データは Groovy の GString としてクエリーに渡されます。
    • 適切な HTTP レスポンスを設定します。
    図 40. 追加するメソッド
    追加するメソッド
    追加するメソッド
  2. Firefox Poster に戻り、http://localhost:8080/resources/incentive を URL として入力します。コンテンツ・エリアには、図 41 に示すように JSON オブジェクトを入力します (このコンテンツは、ダウンロード・ファイルに含まれている <download_root>/sMashArticleSeries/Part1/postInput.txt からペーストすることができます)。
    図 41. POST のテスト
    POST のテスト
    POST のテスト
  3. すると更新が成功したことを示す 204 レスポンスが返されます。ロケーション・ヘッダーが、新たに POST が実行された項目の場所を示す URL になっていることに注目してください。
    図 42. POST レスポンス
    POST レスポンス
    POST レスポンス
  4. データ項目のいずれか (例えば名前) を変更します。Poster 入力に POST URL をコピーして (または末尾に ID を追加して)、PUT を実行してください。
    図 43. PUT リクエスト
    PUT リクエスト
    PUT リクエスト
  5. 場合によってはファイアウォールの設定が原因で、PUT を実行できない場合があります。その場合には POST を介して PUT を実行できるように、X-Method-Override ヘッダーを追加し、Value を PUT に設定してください (図 44 を参照)。ただし、このようにするのは PUT が失敗した場合に限ります。するとレスポンスとして 204 を受け取るはずです。同じ URI で GET を実行して、更新が成功していることを確認してください。
    図 44. POST の上書き
    POST の上書き
    POST の上書き
  6. 同じ URI で今度は DELETE を実行します。
    図 45. DELETE
    DELETE
    DELETE
  7. 同じくレスポンスは 204 となるはずです (図 46 を参照)。GET を実行すると、見つからなかったことを示す 404 が返されます。
    図 46. DELETE の結果
    DELETE の結果
    DELETE の結果

RESTful なリソースをセキュアにする

RESTful なアプリケーションを作成するときには、セキュリティーを考慮する必要があります。このセクションでは、プロバイダー・アプリケーションへのアクセスが許可された人々に対して、インセンティブの POST、PUT、および DELETE メソッドをセキュアにします。GET については、カスタマーがインターネットでインセンティブを検索できるように、セキュアにはしません。

セキュリティー・ルールは zero 構成ファイルに入力します。ここではデフォルトの security.config を使用しますが、別の構成ファイルにセキュリティー情報を保管し、そのファイルを zero.config に含めることもできます。

  1. File Editor を表示し、Recent Files の下に表示された zero.config ファイルを選択します。
    図 47. zero.config
    zero.config
    zero.config
  2. 図 48 に示すセキュリティー・ルールを入力します (このルールは、ダウンロード・ファイルに含まれている <download_root>/sMashArticleSeries/Part1/securityRules.txt からペーストすることができます)。このルールでは、以下の点に注目してください。
    • 必要なパターンを取得するためにデフォルトのルール構成を組み込みますが、条件を指定していることに注目してください。この例の場合、/resources/incentive (およびそれに続く (/*|?) で示されたあらゆるインセンティブと、HTTP メソッドの DELETE、POST、または PUT) と一致する HTTP リクエストを探します。この情報は GlobalContext 内に含まれ、前述のリクエスト・ライフ・サイクルのセキュア・フェーズの間に呼び出されます。
    • 認証タイプとして Basic を指定しています (WebSphere sMash はこの他にも Form、Single Sign-on、Open ID などのタイプをサポートします。WebSphere sMash 「Developer’s Guide」のセキュリティーに関するセクションを参照してください)。その上で、この URI ルールにアクセス可能なグループ、ユーザー、またはロールを指定します。この例では、あらゆる認証済みユーザーと一致する特殊なグループを指定しています。
    図 48. セキュリティー・ルール
    セキュリティー・ルール
    セキュリティー・ルール
  3. WebSphere sMash には、開発に最適なファイル・ベースのデフォルト・レジストリーが用意されています。デフォルト・レジストリーは、後でデプロイする際に LDAP ベースまたはカスタム・ベースのレジストリーに切り替えることができます。このデフォルトのファイル・レジストリーに、zero の CLI を使ってユーザーを作成します。

    Console タブを表示して、Command Prompt を選択します。コマンド zero user create admin passw0rd を入力します (図 49 参照)。

    図 49. ユーザーの作成
    ユーザーの作成
    ユーザーの作成
  4. このコマンドの実行結果は図 50 のとおりです。
    図 50. zero コマンドの実行結果
    zero コマンドの実行結果
    zero コマンドの実行結果

構成を変更したため、アプリケーションを再起動してテストする必要があります。

  1. 右上隅にある Stop をクリックします (図 51 を参照)。
    図 51. アプリケーションの停止
    アプリケーションの停止
    アプリケーションの停止
  2. Run をクリックしてアプリケーションを起動します。
    図 52. アプリケーションの実行
    アプリケーションの実行
    アプリケーションの実行
  3. POSTER ツールに戻り、http://localhost:8080/resources/incentive に対して GET を実行します (図 53 を参照)。GET リクエストはセキュアではないので、前と同じようにリストを取得できます。
    図 53. 非セキュアな GET
    非セキュアな GET
    非セキュアな GET
  4. 前と同じ入力を使用して、POST リクエストを実行します。このコンテンツも postInput.txt (ダウンロード・ファイルに含まれる <download_root>/sMashArticleSeries/Part1/securityRules.txt) からペーストすることができます。
    図 54. POST リクエスト
    POST リクエスト
    POST リクエスト
  5. ユーザー名とパスワードの入力を求めるプロンプトが表示されます。admin/passw0rd と入力してください。
    図 55. セキュリティー・プロンプト
    セキュリティー・プロンプト
    セキュリティー・プロンプト
  6. すると 204 のレスポンスが返され、新しいリソースが作成されます。PUT と DELETE についても、同じようにしてテストすることができます。
    図 56. POST の結果
    POST の結果
    POST の結果

まとめ

この記事では Project Zero に関する前回の記事の内容を更新して、WebSphere sMash の製品コードを使用しました。そして WebSphere sMash について紹介し、この製品がイベント・ベースのアーキテクチャーをベースにしていることを説明しました。アプリケーションのすべての状態を維持する手段は、グローバル・コンテキストです。アプリケーション中心の WebSphere sMash には規約の使用を支援する複数の仮想ディレクトリーがあるため、アプリケーションの構成の量は減ることになります。

今回はWebSphere sMash を使用して、インセンティブ・データを公開する REST ベースのアプリケーションを作成しました。手順のなかでは sMash アプリケーションを作成するための Web ベースの統合開発環境として、新しい AppBuilder も使用しています。そして最後に、sMash のセキュリティー・ルールを使って RESTful なリソースをセキュアにする方法を説明しました。

次の記事では、コンシューマー・アプリケーションを作成する手順をとおして、REST の詳細をさらに掘り下げていきます。次回はもう 1 つの REST サービスの作成パターンとして、ZRM (Zero Resource Model) を使用します。また、Dojo Toolkit を使用して RESTful なリソースに応じたリッチ・インターネット・クライアントも作成する予定です。


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


関連トピック


コメント

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

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Web development, WebSphere
ArticleID=342515
ArticleTitle=IBM WebSphere sMash の紹介: 第 1 回: Web アプリケーションのための RESTful なサービスを作成する
publish-date=09022008