前回はサーバレスなアプリケーションを実現するためのAzureサービス「Azure Functions」について、その概要と実際の関数アプリの作成方法を解説した。今回は、IntelliJ IDEA上でJavaを使って関数を実装し、前回作成した関数アプリにデプロイする一連の手順を紹介する。

Azure Toolkit for IntelliJを使ったプロジェクトの作成

Javaを使ってAzure Functions用の関数を作成するには、Microsoftから提供されているMavenベースのツールを利用するのが一番手軽で確実である。統合開発環境としては、Visual Studio CodeやEclipse、IntelliJ IDEAには、それぞれAzure Functionsにも対応したプラグインが提供されている。各プラグインにはMavenベースのビルドツールと雛形となるアプリケーション・テンプレートも含まれている。

今回は、IntelliJ IDEAを使用して関数を作成する方法を紹介する。IntelliJ IDEAでは、Azureサービス用のプラグイン「Azure Toolkit for IntelliJ」が、Azure Functionsの関数の作成にも対応している。Azure Toolkit for IntelliJのインストール方法などについては第6回記事を参照いただきたい。

  • Azure Toolkit for IntelliJ

    Azure Toolkit for IntelliJ

Azure Toolkit for IntelliJが有効になっていると、新規プロジェクトウィザードでは次のように「Azure Functions」という項目が選択できる。ここで、関数のトリガーの種類を選択して[Next]をクリックする。本稿の例では、HTTPのリクエストで関数が起動する[HTTP Trigger]を選択した。

  • Azure Functionsのプロジェクトを作成

    Azure Functionsのプロジェクトを作成

あとは通常のプロジェクト作成と同様に、パッケージやプロジェクト名、プロジェクトの場所などを設定していけばよい。

  • アーティファクトやパッケージの設定例

    アーティファクトやパッケージの設定例

  • プロジェクト名とプロジェクトの場所の設定例

    プロジェクト名とプロジェクトの場所の設定例

最後に[Finish]をクリックすれば、プロジェクトが作成される。HttpTrigerを選択している場合、srcディレクトリの下に次のように「HttpTrigerFunction」というクラスが生成されている。これが関数を実装する際の雛形となるもので、このクラスのrun()メソッドが関数の処理の本体になっている。

  • 作成された関数の雛形

    作成された関数の雛形

関数をAzure Functionsにデプロイする

HttpTrigerFunctionは、この時点ですでに動作するサンプルになっているので、早速これを前回作成した関数アプリにデプロイしてみよう。IntelliJ IDEAから直接Azure Functionsにデプロイするには、Azure Toolkit for IntelliJを使ってAzureサービスにサインインしておく必要がある。サインインの方法は第6回の記事で詳しく解説しいている。

関数をAzure Functionsにデプロイするには、次のようにプロジェクト名を右クリックして、「Azure」-「Deploy to Azure Functions」を選択する。

  • IntelliJ IDEAから関数をデプロイできる

    IntelliJ IDEAから関数をデプロイできる

すると、次のようなダイアログが表示されるので、ここでデプロイする関数の設定を行う。重要なのは「Functions」の項目で、ここでデプロイする先の関数アプリを選択する。まだ関数アプリが存在しない場合は、この画面から新規に作成することもできる。本稿の例では前回「mynavifunc」という関数アプリを作成したので、これをデプロイ先としている。

  • デプロイの設定例 対象の関数アプリを選ぶ

    デプロイの設定例 対象の関数アプリを選ぶ

[Run]をクリックするとデプロイが実行される。デプロイが完了したら、Runウィンドウにこの関数のエンドポイントとなるURLが表示されるはずだ。

  • デプロイ完了 リクエストのエンドポイントが示されている

    デプロイ完了。リクエストのエンドポイントが示されている

WebブラウザからこのURLにアクセスすると次のような表示になる。

  • パラメータ無しでアクセスした場合

    パラメータ無しでアクセスした場合

この関数は、リクエスト時に「name」パラメータがセットされていないと上のようなレスポンスになる。「https://mynavifunc.azurewebsites.net/api/httptrigger-java?name=MyNavi」のようにnameパラメータをセットしてリクエストすれば、次のように表示される。

  • nameパラメータを付けてアクセスした場合

    nameパラメータを付けてアクセスした場合

アノテーションを利用した関数の実装

それでは、サンプルのHttpTriggerFunctionクラスの中を見てみよう。HttpTriggerFunctionクラスは次のようなコードになっている。

/**
 * Azure Functions with HTTP Trigger.
 */
public class HttpTriggerFunction {
    /**
     * This function listens at endpoint "/api/HttpTrigger-Java". Two ways to invoke it using "curl" command in bash:
     * 1. curl -d "HTTP Body" {your host}/api/HttpTrigger-Java
     * 2. curl {your host}/api/HttpTrigger-Java?name=HTTP%20Query
     */
    @FunctionName("HttpTrigger-Java")
    public HttpResponseMessage run(
            @HttpTrigger(name = "req", methods = {HttpMethod.GET, HttpMethod.POST}, authLevel = AuthorizationLevel.ANONYMOUS) HttpRequestMessage<Optional<String>> request,
            final ExecutionContext context) {
        context.getLogger().info("Java HTTP trigger processed a request.");

        // Parse query parameter
        String query = request.getQueryParameters().get("name");
        String name = request.getBody().orElse(query);

        if (name == null) {
            return request.createResponseBuilder(HttpStatus.BAD_REQUEST).body("Please pass a name on the query string or in the request body").build();
        } else {
            return request.createResponseBuilder(HttpStatus.OK).body("Hello, " + name).build();
        }
    }
}

関数の本体はrun()メソッドで、これには @FunctionNameアノテーションで関数名が指定されている。この関数名はリクエスト時のエンドポイントにもなるものだ。すなわち、HTTPリクエストのURLは「[ホスト名]/api/HttpTrigger-Java」のような形式になる。

run()メソッドは、リクエストの内容が格納されるHttpRequestMessage<Optional<String>>オブジェクトと、実行用のコンテキストが格納されるExecutionContextオブジェクトの2つの引数を受け取る。HttpRequestMessage<Optional<String>>の方には @HttpTriggerアノテーションが付与されている。これが、HTTPトリガーとしての設定を行うためのアノテーションである。

通常、関数のトリガーの設定はfunction.jsonファイルに記述するが、@HttpTriggerアノテーションを使えばJSONファイスの代わりにJavaコード内で設定が行える。この例では、name、methods、authLevelの3つの値をセットしている。nameは関数内で利用される任意の変数名、methodsはリクエストを受け付けるHTTPメソッドの種類で、authLevelは関数を呼び出すためにどのAPIキーが必要かという設定になる。この例ではauthLevelはAuthorizationLevel.ANONYMOUSで、これはAPIキーが不要なことを意味する。

run()メソッドの中身は、リクエストクエリからnameパラメータの値を取得して、値がセットされているか否かでレスポンスの内容を変えるという内容になっている。レスポンスはHttpResponseMessageオブジェクトだが、これはHttpRequestMessageクラスのcreateResponseBuilder()メソッドを利用して作成することができる。

以上がテンプレートから作成されたHTTPトリガー関数の概要だ。次回は引き続き、Javaを使った関数アプリの作成について解説する。