The English version of quarkus.io is the official project site. Translated sites are community supported on a best-effort basis.

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

The quarkus-google-cloud-functions-http extension allows you to write microservices with Quarkus REST (Jakarta REST), Undertow (Servlet), Reactive Routes, or Funqy HTTP, and make these microservices deployable to the Google Cloud Functions runtime.

One Google Cloud Functions deployment can represent any number of Jakarta REST, Servlet, Reactive Routes, or Funqy HTTP endpoints.

这项技术被认为是preview。

preview(预览) 中,不保证向后兼容和在生态系统中的存在。具体的改进可能需要改变配置或API,并且正在计划变得 稳定 。欢迎在我们的 邮件列表 中提供反馈,或在我们的 GitHub问题列表 中提出问题。

For a full list of possible statuses, check our FAQ entry.

先决条件

完成这个指南,你需要:

解决方案

This guide walks you through generating a sample project followed by creating three HTTP endpoints written with Jakarta REST APIs, Servlet APIs, Reactive Routes, or Funqy HTTP APIs. Once built, you will be able to deploy the project to Google Cloud.

If you don’t want to follow all these steps, you can go right to the completed example.

克隆 Git 仓库: git clone https://github.com/quarkusio/quarkus-quickstarts.git ,或下载一个 存档

The solution is located in the google-cloud-functions-http-quickstart directory.

创建Maven部署项目

Create an application with the quarkus-google-cloud-functions-http extension. You can use the following Maven command to create it:

CLI
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

创建Grade项目,请添加 --gradle 或者 --gradle-kotlin-dsl 参数。

For more information about how to install and use the Quarkus CLI, see the Quarkus CLI guide.

Maven
mvn io.quarkus.platform:quarkus-maven-plugin:3.17.4: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

创建Grade项目,请添加 -DbuildTool=gradle 或者 -DbuildTool=gradle-kotlin-dsl 参数。

For Windows users:

  • If using cmd, (don’t use backward slash \ and put everything on the same line)

  • If using Powershell, wrap -D parameters in double quotes e.g. "-DprojectArtifactId=google-cloud-functions-http"

Login to Google Cloud

Login to Google Cloud is necessary for deploying the application. It can be done as follows:

gcloud auth login

Creating the endpoints

For this example project, we will create four endpoints, one for Quarkus REST (Jakarta REST), one for Undertow (Servlet), one for Reactive routes and one for Funqy HTTP.

These various endpoints are for demonstration purposes. For real life applications, you should choose one of these technologies and stick to it.

If you don’t need endpoints of each type, you can remove the corresponding extensions from your pom.xml.

The Jakarta REST endpoint

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";
    }
}

The Servlet endpoint

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);
    }
}

The Reactive Routes endpoint

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");
    }
}

The Funqy HTTP endpoint

import io.quarkus.funqy.Funq;

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

Build and Deploy to Google Cloud

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

Package your application using the standard mvn clean package command. The result of the previous command is a single JAR file inside the target/deployment directory that contains the classes and the dependencies of the project.

Then you will be able to use gcloud to deploy your function to 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

The entry point must always be set to io.quarkus.gcp.functions.http.QuarkusHttpFunction as this is the class that integrates Cloud Functions with Quarkus.

The first time you launch this command, you can have the following error message:

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.

This means that Cloud Build is not activated yet. To overcome this error, open the URL shown in the error, follow the instructions and then wait a few minutes before retrying the command.

This command will give you as output a httpsTrigger.url that points to your function.

You can then call your endpoints via:

  • For Jakarta REST: {httpsTrigger.url}/hello

  • For servlet: {httpsTrigger.url}/servlet/hello

  • For Reactive Routes: {httpsTrigger.url}/vertx/hello

  • For Funqy: {httpsTrigger.url}/funqy

Testing locally

The easiest way to locally test your function is using the Cloud Function invoker JAR.

You can download it via Maven using the following command:

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

Before using the invoker, you first need to build your function via mvn package.

Then you can use it to launch your function locally.

java -jar java-function-invoker-1.3.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.

Your endpoints will be available on http://localhost:8080.

下一步做什么?

You can use our Google Cloud Functions Funqy binding to use Funqy, a provider-agnostic function as a service framework, that allow to deploy HTTP function or Background function to Google Cloud.

Related content