Funqy
Quarkus Funqy 是 Quarkus 的无服务器策略的一部分,旨在提供一个可移植的 Java API,用于编写可部署到各种 FaaS 环境(如 AWS Lambda、Azure Functions、Google Cloud Functions、Knative 和 Knative Events(Cloud Events))的函数。它也可以作为独立服务使用。
由于 Funqy 是一个跨越多种不同云/函数提供商和协议的抽象,因此它必须是一个非常简单的 API,因此可能不具备您在其他远程抽象中习惯的所有功能。一个不错的影响是 Funqy 尽可能优化和小型化。这意味着,由于 Funqy 在灵活性上做出了一点牺牲,您将获得一个几乎没有开销的框架。
Funqy 基础知识
Funqy API 很简单。用 @Funq
注释一个方法。此方法只能有一个可选的输入参数,并且可以返回响应,也可以不返回响应。
import io.quarkus.funqy.Funq;
public class GreetingFunction {
@Funq
public String greet(String name) {
return "Hello " + name;
}
}
Java 类也可以用作输入和输出,并且必须遵循 Java bean 约定并具有默认构造函数。声明为参数或返回类型的 Java 类型是 Funqy 运行时期望的类型。Funqy 在构建时进行类型内省以加快启动速度,因此运行时 Funqy 编组层不会注意到任何派生类型。
这是一个使用 POJO 作为输入和输出类型的示例。
public class GreetingFunction {
public static class Friend {
String name;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
}
public static class Greeting {
String msg;
public Greeting() {}
public Greeting(String msg) { this.msg = msg }
public String getMessage() { return msg; }
public void setMessage(String msg) { this.msg = msg; }
}
@Funq
public Greeting greet(Friend friend) {
return new Greeting("Hello " + friend.getName());
}
}
异步响应式类型
Funqy 支持 SmallRye Mutiny 的 Uni
响应式类型作为返回类型。唯一的要求是 Uni
必须填写泛型类型。
import io.quarkus.funqy.Funq;
import io.smallrye.mutiny.Uni;
public class GreetingFunction {
@Funq
public Uni<Greeting> reactiveGreeting(String name) {
...
}
}
函数名称
函数名默认为方法名,且区分大小写。如果您希望您的函数以不同的名称引用,请如下参数化 @Funq
注释
import io.quarkus.funqy.Funq;
public class GreetingFunction {
@Funq("HelloWorld")
public String greet(String name) {
return "Hello " + name;
}
}
Funqy DI
每个 Funqy Java 类都是一个 Quarkus Arc 组件,并支持通过 CDI 或 Spring DI 进行依赖注入。Spring DI 要求在构建中包含 quarkus-spring-di
依赖项。
Funqy 类的默认对象生命周期为 @Dependent
。
import io.quarkus.funqy.Funq;
import jakarta.inject.Inject;
import jakarta.enterprise.context.ApplicationScoped;
@ApplicationScoped
public class GreetingFunction {
@Inject
GreetingService service;
@Funq
public Greeting greet(Friend friend) {
Greeting greeting = new Greeting();
greeting.setMessage(service.greet(friend.getName()));
return greeting;
}
}
上下文注入
Funqy API 通常不允许您注入或使用特定于协议(例如 HTTP)或函数 API(例如 AWS Lambda)的抽象。不过,也有例外,您可能能够注入特定于您正在部署的环境的上下文信息。
我们不建议注入特定于运行时的上下文信息。请保持您的函数可移植。 |
上下文信息通过 @Context
注释注入,该注释可用于函数参数或类字段。一个很好的例子是我们 Funqy Knative Cloud Events 集成随附的 io.quarkus.funqy.knative.events.CloudEvent
接口。
import io.quarkus.funqy.Funq;
import io.quarkus.funqy.Context;
import io.quarkus.funqy.knative.events.CloudEvent;
public class GreetingFunction {
@Funq
public Greeting greet(Friend friend, @Context CloudEvent eventInfo) {
System.out.println("Received greeting request from: " eventInfo.getSource());
Greeting greeting = new Greeting();
greeting.setMessage("Hello " + friend.getName()));
return greeting;
}
}
我应该使用 Funqy 吗?
在过去十年中,HTTP 上的 REST 已成为编写服务的非常流行的方式。虽然 Funqy 具有 HTTP 绑定,但它并不能替代 REST。由于 Funqy 必须跨各种协议和函数云平台工作,因此它非常简约且受限制。例如,如果您使用 Funqy,您将无法链接(考虑 URIs)到您的函数输出的数据。您还将失去利用诸如 cache-control
和条件 GET 等出色 HTTP 功能的能力。许多开发人员对此会没事的,因为许多人不会使用这些 REST/HTTP 功能或样式。您必须决定您属于哪个阵营。Quarkus 通过 Jakarta REST、Spring MVC、Vert.x Web 和 Servlet 支持与各种云/函数提供商的 REST 集成,但使用该方法也有一些缺点。例如,如果您想使用 AWS Lambda 进行 HTTP,这需要您使用 AWS API Gateway,这可能会减慢部署和冷启动时间,甚至花费更多。
Funqy 的目的是允许您编写跨提供商的函数,这样您就可以摆脱您当前的函数提供商,例如,如果他们开始向您收取更高的服务费。您可能不想使用 Funqy 的另一个原因是,如果您需要访问目标函数环境的特定 API。例如,开发人员通常希望在 Lambda 上访问 AWS Context。在这种情况下,我们建议他们最好使用 Quarkus AWS Lambda 集成。