REST API 拡張の作成

REST API 拡張は、フォーム/ページとサードパーティ・システム(Bonita BPM Engine を含む)間を連携するソリューションを提供します。 ビジネス データ、Bonita BPM Engine API や外部の情報システム(データベース、Webサービス、LDAP ディレクトリ…など)のデータアクセスに使用できます。これにより、フロントエンド(フォーム、ページなどのユーザーインターフェース画面)とバックエンド(プロセス)間の明確な分離を可能にします。

前提条件

REST API 拡張を開発するための前提条件は、

  • Java/Groovy 開発の専門知識を有すること。
  • Maven の基本知識を有すること。
  • Maven central repository へのアクセスが可能なこと。 あなたのプロバイダーがインターネット アクセスを制限している場合は、プロキシ設定のコンフィグレーション、あるいはミラーリポジトリの作成で解決します。

サンプルコードの解説

以下のセクションでは、REST API 拡張の作り方を解説します。例として、Bonita BPM Engine を使用してユーザー情報 (first name, last name, email address)を提供する REST API 拡張を作成します。

新しい REST API 拡張スケルトンを生成する

  1. [開発] メニューで [REST API 拡張] > [新規…] を選択します。
  2. [名前] を入力します。例えば、「User informations REST API Extension 」。
  3. [説明] を入力します。例えば、 「Query Bonita BPM Engine to retrieve user informations 」。
  4. [パッケージ] を入力します。 これは、アーティファクトの Group id をセットするために使用します。 例えば、「com.company.rest.api 」。
  5. [プロジェクト名] を入力します。例えば、 「userInformationRestAPIExension 」。
  6. [次へ] をクリックします。
  7. この REST API 拡張に対し、[パス テンプレート] を入力します。 例えば、「userInformation 」とすると、この API のアクセス ポイントは次のパターンでURLを指定することになります。
    {bonita_portal_context}/API/extension/userInformation
  8. このサンプル REST API 拡張は、ビジネスデータをアクセスしないので、”BDM の依存関係を追加” のチェック ボックスをアンチェックにします。
  9. この拡張に対し[アクセス権限] を定義します(デフォルトの設定を置き換えます)。例えば、「read_user_information 」。
  10. [次へ] をクリックします。
  11. この画面は、API に渡される[URL パラメータ] を定義します。結果のページネーションを可能にするため、デフォルトでは、 pc のパラメータが定義されます。 このサンプル API ではユーザーのリストを戻したいので、このパラメータをそのまま採用します。
  12. [新規作成] をクリックします。

コードを書く

Main のソースコード

最初のステップは、REST API では コンフィグレーション パラメータ を定義する必要がないため、REST API に関係するそれらのファイルやコードを削除します。

  1. src/main/resources フォルダから configuration.properties ファイルを削除します。(ファイルを削除するには、そのファイル名にフォーカスし “Delete” キーを押します)
  2. 同様に、src/test/resources フォルダから testConfiguration.properties を削除します。
  3. コンフィグレーション ファイルの mock セットアップを削除します。そのためには、IndexTest.groovy をソースコードを開き、 setup() メソッドに進んで resourceProvider....で始まる行を削除します。
  4. Index.groovy ファイル内のコンフィグレーション使用例(”Here is an example of you can…” で始まるコメント)を削除します。

次に Index.groovy 内にビジネス ロジックを追記します。 doHandle のメソッド内の “Your code goes here” のコメントに進んで、その直下に次のコードを追記します(なお、既存の resultreturn ステートメントは削除すること)。

// パラメータを文字列から int に変換する
p = p as int
c = c as int

// ユーザー情報を格納するためのリストを初期化する
def usersInformation = []

// ユーザーのリストを取得する
List<User> users = context.apiClient.identityAPI.getUsers(p*c, c, UserCriterion.FIRST_NAME_ASC)

// 各ユーザーを繰り返す
for (user in users) {
    // ユーザーの追加情報を取得する (email アドレスを含む)
    ContactData contactData = context.apiClient.identityAPI.getUserContactData(user.id, false)

    // 現在の user first name, last name と email address を持つマップ(連想配列)を作成する
    def userInformation = [firstName: user.firstName, lastName: user.lastName, email: contactData.email]

    // 現在のユーザー情報をグローバルのリストに追加する
    usersInformation << userInformation
}
// 結果をセットする
def result = [p: p, c: c, userInformation: usersInformation]

int startIndex = p*c
int endIndex = p*c + users.size() - 1

// JSON 形式で結果を返す
return buildPagedResponse(responseBuilder, new JsonBuilder(result).toPrettyString(), startIndex, endIndex, context.apiClient.identityAPI.numberOfUsers)

最後に、Ctrl+Shift+O キー(インポートの再編成)を押して、欠落しているすべてのimportを追加します。

Test のソースコード

次に REST API 拡張の動きを検証するため、IndexTest.groovy を編集し、test を更新する必要があります。

最初のステップは、Engine API である Identity API のような外部依存の mock をいくつか定義することです。既存コードの後に次の mock 宣言を追加します。

def apiClient = Mock(APIClient)
def identityAPI = Mock(IdentityAPI)
def april = Mock(User)
def william = Mock(User)
def walter = Mock(User)
def contactData = Mock(ContactData)

次にこれらの mock の全般的な動きを定義する必要があります。 setup() メソッドは、次のコンテンツを持つべきです。

context.apiClient >> apiClient
apiClient.identityAPI >> identityAPI
identityAPI.getUsers(0, 2, _) >> [april, william]
identityAPI.getUsers(1, 2, _) >> [william, walter]
identityAPI.getUsers(2, 2, _) >> [walter]

april.firstName >> "April"
april.lastName >> "Sanchez"
william.firstName >> "William"
william.lastName >> "Jobs"
walter.firstName >> "Walter"
walter.lastName >> "Bates"

identityAPI.getUserContactData(*_) >> contactData
contactData.email >> "test@email"

次にテスト メソッドを定義します。 既存の should_return_a_json_representation_as_result テスト メソッドを次のものに置き換えます。

def should_return_a_json_representation_as_result() {
    given: "RestAPIController"
    def index = new Index()
    // リクエストを各パラメータの値でシミュレートする
    httpRequest.getParameter("p") >> "0"
    httpRequest.getParameter("c") >> "2"

    when: " REST API を呼び出し中"
    def apiResponse = index.doHandle(httpRequest, new RestApiResponseBuilder(), context)

    then: " JSON 形式がレスポンス本文内に戻される"
    def jsonResponse = new JsonSlurper().parseText(apiResponse.response)
    // 戻されたレスポンスを検証する
    apiResponse.httpStatus == 200
    jsonResponse.p == 0
    jsonResponse.c == 2
    jsonResponse.userInformation.equals([
        [firstName: "April" , lastName: "Sanchez" , email: "test@email" ],
        [firstName: "William" , lastName: "Jobs" , email: "test@email" ]
    ]);
}

これで単体テストの実行が可能になりました。IndexTest.groovy ファイルを右クリックして、 REST API 拡張 > JUnit テストの実行をクリックします。JUnit のビューはテスト結果を表示します。すべてのテストに合格すべきです。

REST API 拡張をビルド、デプロイ、テストする

Studio は、 REST API 拡張をビルドし、Studio 内のテスト環境にデプロイします。

最初のステップは、Studio 内のテスト環境に置かれたあなたのREST API 拡張に対しセキュリティを設定することです。

  1. [開発] メニューで [REST API 拡張] > [権限のマッピングを編集] を選択します。
  2. ファイルの最終行に profile|User=[read_user_information] を追記します。これは、ユーザープロファイルでログインしたすべての人にアクセス権限が許諾されることを意味します。
  3. このファイルを保存して閉じます。

これであなたのREST API 拡張をビルドしてデプロイすることができます。

  1. [開発] メニューで [REST API 拡張] > [デプロイ…] を選択します。
  2. userInformationRestAPIExension REST API 拡張を選択します。
  3. デプロイ ボタンをクリックします。
  4. クールバーでポータルのアイコンをクリックして、ブラウザに Bonita BPM ポータル画面をオープンします。
  5. このポータルの利用者をシステム管理者プロファイルに変更します。
  6. [リソース ] タブに進んでREST API 拡張リソースのリストに User information REST API extension があることを確認します。

最後にあなたのREST API 拡張をテストします。

  1. webブラウザで新しいタブをオープンします。
  2. URLのフィールドで http://localhost:8080/bonita/API/extension/userInformation?p=0&c=10 を入力してください。
  3. JSON レスポンス本文が表示されるはずです。

この REST API 拡張は、UI デザイナーでフォームやページの External API 変数として使用できます。

すぐ使えるサンプル

あなたは、以上のチュートリアルで解説した REST API 拡張 をダウンロードすることができます。また、データベースのアクセス事例として、データソース REST API 拡張 も参考にしてください。

情報: 以下は、オープンソース ジャパンからの追加情報です。

エディタのショートカットキー

このREST APT  拡張のエディタは、eclipseのエディタを使用していますから、 Ctrl+Shift+L キーを押すと下図のショートカットキーのリストが画面右下に表示されます。たとえば、「検索と置換」は Ctrl+F です。

eclipseShotcutKeyList

JUnit のテストをスキップしたい場合

ウィザードで生成された Index.Text.groovy 内のdef setup() {…} 以下のコードをコメントアウトするか、削除します。

デプロイを繰り返すことは可能か?

デプロイ後に再デプロイした場合、BPM エンジンにデプロイ済みのREST API 拡張リソースは自動で上書き変更されます。したがって、コード変更後、再デプロイするとその更新版を最新のREST API 拡張として即使用可能になります。

バージョン番号の変更はどうのようにするのか?

下図のように pom.xml をクリックして Version を変更します。

pomUpdate

REST API 拡張をアクセスしたとき、HTTP 403 エラーが発生する

当該のREST API 拡張にアクセス権限設定を疑ってください。このサンプルの場合、「権限のマッピングを編集」で” profile|User=[read_user_information]” が適切に設定されていない可能性があります。もし、ユーザープロファイルに複数の権限をマッピングする場合は、下図のように1行で指定します。

profileSetting

サブスクリプション版のStudioで作成/ビルドしたREST API 拡張をコミュニティ版プラットフォームにデプロイしてコールすることは可能か?

はい、可能です。

ただし、REST API 拡張のコードをコミュニティ版プラットフォーム上で実行するには、サブスクリプション仕様を意味する “com.bonitasoft” の Java packages を使用しないで実装する必要があります。もし、そうせずにコミュニティ版プラットフォーム上でその REST API 拡張を実行した場合は、ブラウザは、HTTP のステータスコード = 500を返し、エンジンログには、コンパイルエラー(compilation error)の状態が記録されます。

新しいREST API 拡張をStudioで作成したとき、デフォルトは、ターゲットをサブスクリプション版プラットフォームを前提にしており、サブスクリプション版固有の要素を統合するMavenプロジェクトが生成されます。次の点がコミュニティ版プラットフォームに適合していない要素です。

  • Maven の依存性
  • 生成した実装の中にいくつかの “com.bonitasoft” Java package がインポートされている

これらの要素は、Mavenプロジェクト生成(StudioでREST API 拡張を作成)後に、コミュニティ版プラットフォームに適合するREST API 拡張に変更することができます。

そうするためには、以下の3つの変更が必要です。

  1. pom.xml ファイルの変更
    次の依存性を置き換える
    変更前:

    <dependency>
    <groupId>com.bonitasoft.web</groupId>
    <artifactId>bonita-web-extensions-sp</artifactId>
    <version>${bonita.version}</version>
    <scope>provided</scope>
    </dependency>

    変更後:

    <dependency>
    <groupId>org.bonitasoft.web</groupId>
    <artifactId>bonita-web-extensions</artifactId>
    <version>${bonita.version}</version>
    <scope>provided</scope>
    </dependency>
  2. Index.groovy ファイルの変更
    次のJava インポートを置き換える
    変更前:

    import com.bonitasoft.web.extension.rest.RestAPIContext
    import com.bonitasoft.web.extension.rest.RestApiController

    変更後:

    import org.bonitasoft.web.extension.rest.RestAPIContext
    import org.bonitasoft.web.extension.rest.RestApiController
  3. IndexTest.groovy ファイルの変更
    次のJava インポートを置き換える
    変更前:

    import com.bonitasoft.web.extension.rest.RestAPIContext

    変更後:

    import org.bonitasoft.web.extension.rest.RestAPIContext