Google Cloud Functions (Serverless) with Quarkus REST, Undertow, or Reactive Routes

preview

quarkus-google-cloud-functions-http エクステンションを使用すると、Quarkus REST(Jakarta REST)、Undertow(サーブレット)、Reactive Routes、または Funqy HTTP を使用してマイクロサービスを記述し、これらのマイクロサービスを Google Cloud Functions ランタイムにデプロイできるようになります。

Google Cloud Functionsのデプロイメント1つで、Jakarta REST、Servlet、Reactive Routes、Funqy HTTP エンドポイントをいくつでも表すことができます。

この技術は、previewと考えられています。

preview では、下位互換性やエコシステムでの存在は保証されていません。具体的な改善には設定や API の変更が必要になるかもしれませんが、 stable になるための計画は現在進行中です。フィードバックは メーリングリストGitHub の課題管理 で受け付けています。

とりうるステータスの完全なリストについては、 FAQの項目 を参照してください。

前提条件

このガイドを完成させるには、以下が必要です:

ソリューション

このガイドでは、サンプルプロジェクトを生成し、Jakarta REST API、Servlet API、Reactive Routes、またはFunqy HTTP APIで書かれた3つのHTTPエンドポイントを作成する方法を説明します。ビルドが完了したら、プロジェクトをGoogle Cloudにデプロイすることができるようになります。

これらの手順を順にすべて実行しない場合、完成したサンプルを以下で確認できます。

git clone https://github.com/quarkusio/quarkus-quickstarts.git で Git リポジトリーをクローンします。または、https://github.com/quarkusio/quarkus-quickstarts/archive/main.zip[アーカイブ] をダウンロードします。

ソリューションは google-cloud-functions-http-quickstart ディレクトリ にあります。

Maven デプロイメントプロジェクトの作成

quarkus-google-cloud-functions-http のエクステンションを持つアプリケーションを作成します。以下のMavenコマンドで作成することができます:

コマンドラインインタフェース
quarkus create app org.acme:google-cloud-functions-http \
    --extension='google-cloud-functions-http,rest-jackson,undertow,reactive-routes,funqy-http' \
    --no-code
cd google-cloud-functions-http

Gradleプロジェクトを作成するには、 --gradle または --gradle-kotlin-dsl オプションを追加します。

Quarkus CLIのインストールと使用方法の詳細については、 Quarkus CLI ガイドを参照してください。

Maven
mvn io.quarkus.platform:quarkus-maven-plugin:3.39.2:create \
    -DprojectGroupId=org.acme \
    -DprojectArtifactId=google-cloud-functions-http \
    -Dextensions='google-cloud-functions-http,rest-jackson,undertow,reactive-routes,funqy-http' \
    -DnoCode
cd google-cloud-functions-http

Gradleプロジェクトを作成するには、 -DbuildTool=gradle または -DbuildTool=gradle-kotlin-dsl オプションを追加します。

Windowsユーザーの場合:

  • cmdを使用する場合、(バックスラッシュ \ を使用せず、すべてを同じ行に書かないでください)。

  • Powershellを使用する場合は、 -D パラメータを二重引用符で囲んでください。例: "-DprojectArtifactId=google-cloud-functions-http"

Google Cloud にログイン

アプリケーションのデプロイには Google Cloud へのログインが必要で、以下のように行うことが出来ます:

gcloud auth login

エンドポイントの作成

このサンプルプロジェクトでは、Quarkus REST(Jakarta REST)、Undertow(Servlet)、Reactive routes、 Funqy HTTPの4つのエンドポイントを作成します。

これらの様々なエンドポイントはデモンストレーションのためのものです。 実際のアプリケーションでは、これらの技術の中から1つを選択し、それにこだわるべきです。

各タイプのエンドポイントが不要な場合は、対応するエクステンションを pom.xml から削除することができます。

Jakarta RESTエンドポイント

import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;

@Path("/hello")
public class GreetingResource {

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String hello() {
        return "Hello from Quarkus REST";
    }
}

サーブレットエンドポイント

import java.io.IOException;

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

@WebServlet(name = "ServletGreeting", urlPatterns = "/servlet/hello")
public class GreetingServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setStatus(200);
        resp.addHeader("Content-Type", "text/plain");
        resp.getWriter().write("hello");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String name = req.getReader().readLine();
        resp.setStatus(200);
        resp.addHeader("Content-Type", "text/plain");
        resp.getWriter().write("hello " + name);
    }
}

Reactive Routesエンドポイント

import static io.quarkus.vertx.web.Route.HttpMethod.GET;

import io.quarkus.vertx.web.Route;
import io.vertx.ext.web.RoutingContext;

public class GreetingRoutes {
    @Route(path = "/vertx/hello", methods = GET)
    void hello(RoutingContext context) {
        context.response().headers().set("Content-Type", "text/plain");
        context.response().setStatusCode(200).end("hello");
    }
}

Funqy HTTP エンドポイント

import io.quarkus.funqy.Funq;

public class GreetingFunqy {
    @Funq
    public String funqy() {
        return "Make it funqy";
    }
}

アプリケーションのビルドと Google Cloud へのデプロイ

Quarkus forces a packaging of type uber-jar for your function as Google Cloud Function deployment requires a single JAR.

標準の mvn clean package コマンドを使用して、アプリケーションをパッケージ化します。前述のコマンドの結果、 target/deployment ディレクトリ内に、プロジェクトのクラスと依存関係を含む単一の JAR ファイルが作成されます。

そして、 gcloud を使って、機能を Google Cloud にデプロイすることができるようになります。

We will use the Java 21 runtime, but you can switch to the Java 17 runtime by using --runtime=java17 instead of --runtime=java21 on the deploy commands.
gcloud functions deploy quarkus-example-http \
  --entry-point=io.quarkus.gcp.functions.http.QuarkusHttpFunction \
  --runtime=java21 --trigger-http --allow-unauthenticated --source=target/deployment

このクラスはCloud FunctionsとQuarkusを統合するクラスであるため、エントリーポイントは常に io.quarkus.gcp.functions.http.QuarkusHttpFunction に設定する必要があります。

このコマンドを初めて起動したときには、以下のようなエラーメッセージが表示されることがあります:

ERROR: (gcloud.functions.deploy) OperationError: code=7, message=Build Failed: Cloud Build has not been used in project <project_name> before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/cloudbuild.googleapis.com/overview?project=<my-project> then retry.

これは、Cloud Build がまだ有効化されていないことを意味します。このエラーを解決するには、エラーに表示されている URL を開き指示に従った後、数分待ってからコマンドを再試行してください。

このコマンドは、あなたの関数を指す url を出力として提供します。

そして、エンドポイントを経由して呼び出すことができます:

  • Jakarta REST の場合: {url}/hello

  • サーブレットの場合: {url}/servlet/hello

  • Reactive Routes の場合: {url}/vertx/hello

  • Funqy の場合: {url}/funqy

ローカルでのテスト

関数をローカルでテストする最も簡単な方法は、Cloud Function invoker JAR を使用することです。

以下のコマンドで Maven 経由でダウンロードできます。

mvn dependency:copy \
  -Dartifact='com.google.cloud.functions.invoker:java-function-invoker:2.0.0' \
  -DoutputDirectory=.

invokerを使用する前に、 mvn package で関数をビルドする必要があります。

そして、それを使ってローカルに機能を立ち上げることができます。

java -jar java-function-invoker-2.0.0.jar \
  --classpath target/deployment/google-cloud-functions-http-1.0.0-SNAPSHOT-runner.jar \
  --target io.quarkus.gcp.functions.http.QuarkusHttpFunction
The --classpath parameter needs to be set to the previously packaged JAR that contains your function class and all Quarkus related classes.

エンドポイントは http://localhost:8080 で利用できます。

What’s next?

Google Cloud Functions Funqy バインディング を使用すると、プロバイダに依存しない Service as a Service フレームワークである Funqy を使用することができ、HTTP 関数や Background 関数を Google Cloud にデプロイすることができます。