Funqy HTTP Binding (Standalone)
指南将逐步介绍快速入门代码,向您展示如何部署 Funqy 作为独立服务,以及使用 HTTP 调用 Funqy 函数。
Funqy HTTP 绑定不会替代通过 HTTP 的 REST。由于 Funqy 需要在许多不同的协议和函数提供程序之间实现可移植性,因此其 HTTP 绑定非常极简,您将失去 REST 功能,例如链接以及利用缓存控制和条件 GET 等 HTTP 功能的能力。您可能希望考虑使用 Quarkus 的 Jakarta REST、Spring MVC 或 Vert.x Web Reactive Routes 支持,尽管 Funqy 将比这些替代方案(除了仍然非常快的 Vert.x)具有更少的开销。
Prerequisites
include::./_includes/prerequisites.adoc[]* 阅读有关 Funqy Basics 的信息。这是一篇短文!
The Quickstart
克隆 Git 存储库: git clone $${quickstarts-base-url}.git
,或下载 $${quickstarts-base-url}/archive/main.zip[存档]。
解决方法位于 funqy-http-quickstart
directory 中。
Maven Dependencies
要编写 Funqy HTTP 函数,只需将 quarkus-funqy-http
依赖项包含到您的 Quarkus pom.xml
文件中:
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-funqy-http</artifactId>
</dependency>
Execute Funqy HTTP functions
执行函数的 URL 路径是函数名称。例如,如果您的函数名称为 foo
,则执行函数的 URL 路径将为 /foo
。
可以使用 HTTP POST 或 GET 方法调用函数。函数的返回值使用 Jackson JSON 库编组到 JSON 中。可以使用 Jackson 注释。如果您的函数有输入参数,POST 调用必须使用 JSON 作为输入类型。Jackson 也用于此处进行取消编组。
您可以通过将浏览器指向 [role="bare"][role="bare"]http://localhost:8080/hello 来调用在 PrimitiveFunctions.java 中定义的 hello
函数。
调用快速入门中的其他函数需要 HTTP POST。要执行在 GreetingFunction.java 中定义的 greet
函数,请调用此 curl 脚本。
curl "http://localhost:8080/greet" \
-X POST \
-H "Content-Type: application/json" \
-d '{"name":"Bill"}'
也可以使用标准的 JSON 映射将基本类型传递为输入。若要执行在 PrimitiveFunctions.java 中定义的 toLowerCase
函数,请调用此 curl 脚本:
curl "http://localhost:8080/toLowerCase" \
-X POST \
-H "Content-Type: application/json" \
-d '"HELLO WORLD"'
若要执行在 PrimitiveFunctions.java 中定义的 double
函数,请调用此 curl 脚本:
curl "http://localhost:8080/double" \
-X POST \
-H "Content-Type: application/json" \
-d '2'
GET Query Parameter Mapping
对于 GET 请求,Funqy HTTP 绑定还具有用于函数输入参数的查询参数映射。只有 bean 样式类和 java.util.Map
可以用于您的输入参数。对于 bean 样式类,查询参数名称映射到 bean 类上的属性。这里有一个简单的 Map
示例:
@Funq
public String hello(Map<String, Integer> map) {
...
}
键值必须是基本类型(char 除外)或 String
。值可以是基本类型(char 除外)、String
、OffsetDateTime
或复杂 bean 样式类。对于上述示例,以下是相应的 curl 请求:
curl "http://localhost:8080/a=1&b=2"
hello
函数的 map
输入参数将具有键值对:a
到 1
、b
到 2
。
bean 样式类也可以用作输入参数类型。这里有一个示例:
public class Person {
String first;
String last;
public String getFirst() { return first; }
public void setFirst(String first) { this.first = first; }
public String getLast() { return last; }
public void setLast(String last) { this.last = last; }
}
public class MyFunctions {
@Funq
public String greet(Person p) {
return "Hello " + p.getFirst() + " " + p.getLast();
}
}
属性值可以是除 char
以外的任何基本类型。它也可以是 String
和 OffsetDateTime
。OffsetDateTime
查询参数值必须采用 ISO-8601 格式。
可以使用 HTTP GET 和查询参数对此进行调用:
curl "http://localhost:8080/greet?first=Bill&last=Burke"
在上面的请求中,查询参数名称映射到输入类中对应的属性。
输入类也可以具有嵌套的 bean 类。对上一个示例进行扩展:
public class Family {
private Person dad;
private Person mom;
public Person getDad() { return dad; }
public void setDad(Person dad) { this.dad = dad; }
public Person getMom() { return mom; }
public void setMom(Person mom) { this.mom = mom; }
}
public class MyFunctions {
@Funq
public String greet(Family family) {
...
}
}
在这种情况下,嵌套值的查询参数使用 .
表示法。例如:
curl "http://localhost:8080/greet?dad.first=John&dad.last=Smith&mom.first=Martha&mom.last=Smith"
java.util.List
和 Set
也支持作为属性值。例如:
public class Family {
...
List<String> pets;
}
public class MyFunctions {
@Funq
public String greet(Family family) {
...
}
}
若要调用 GET 请求,只需多次列出 pets
查询参数即可。
curl "http://localhost:8080/greet?pets=itchy&pets=scratchy"
对于更复杂类型,List
和 Set
成员必须在 query 参数中具有一个标识符。例如:
public class Family {
...
List<Person> kids;
}
public class MyFunctions {
@Funq
public String greet(Family family) {
...
}
}
每个 kids
查询参数都必须标识它们引用的 kid,以便运行时能够找出哪些属性值属于列表中哪些成员。以下是 curl 请求:
curl "http://localhost:8080/greet?kids.1.first=Buffy&kids.2.first=Charlie"
上述 URL 使用值 1
和 2
来标识列表的目标成员,但可以使用任何唯一的字符串。
属性也可以是 java.util.Map
。映射的键可以是任何基本类型和 String
。例如:
public class Family {
...
Map<String, String> address;
}
public class MyFunctions {
@Funq
public String greet(Family family) {
...
}
}
相应的调用将如下所示:
curl "http://localhost:8080/greet?address.state=MA&address.city=Boston"
如果您的 Map
值是复杂类型,那么只需通过在最后添加要设置的属性来继续表示法即可。
public class Family {
...
Map<String, Address> addresses;
}
public class MyFunctions {
@Funq
public String greet(Family family) {
...
}
}
curl "http://localhost:8080/greet?addresses.home.state=MA&addresses.home.city=Boston"