Standalone Web Applications
函数可以自动导出为 HTTP 终结点。 `spring-cloud-function-web`模块有自动配置,当它包含在 Spring Boot Web 应用程序中时激活(带有 MVC 支持)。还有一个`spring-cloud-starter-function-web`来收集所有可选的依赖项,以防你只想要一个简单的入门体验。 通过激活 Web 配置,你的应用程序将有一个 MVC 终结点(默认为“/”,但可以用`spring.cloud.function.web.path`配置),它可以用来访问应用程序上下文中函数,函数名成为 URL 路径的一部分。支持的内容类型是纯文本和 JSON。
重要的是要明白,虽然 SCF 提供了将函数式 Bean 导出为 REST 端点的能力,但它并不是 Spring MVC/WebFlux 等的替代品。它主要是为了适应_stateless serverless patterns_,在这种情况下,您只想让一些无状态功能通过 HTTP 暴露。
Method | Path | Request | Response | Status |
---|---|---|---|---|
GET |
/{supplier} |
- |
指定供应商的项目 |
200 OK |
POST |
/{consumer} |
JSON object or text |
镜像输入并将请求正文推入使用者 |
202 Accepted |
PUT |
/{consumer} |
JSON object or text |
镜像输入并将请求正文推入使用者 |
202 Accepted |
DELETE |
/{consumer} |
JSON object or text |
- |
204 NO CONTENT |
POST |
/{function} |
JSON object or text |
应用指定函数的结果 |
200 OK |
PUT |
/{function} |
JSON object or text |
应用指定函数的结果 |
200 OK |
GET |
/{function}/{item} |
- |
将该项目转换为一个对象,并返回应用该函数的结果 |
200 OK |
如上表所示,终结点行为取决于方法和传入请求数据类型。当传入数据单值时,而目标函数被显然声明为单值(即不返回集合或`Flux`),则响应也将包含一个单值。对于多值响应,客户端可以通过发送 Accept: text/event-stream
来请求服务器发送事件流。
`Message<?>`中输入和输出声明的函数和消费者会将请求头视为_消息头_,而输出_消息头_将被转换为 HTTP 头。消息的_有效负载_将是`body`或空字符串(如果没有_body_或它为 null)。
当发布文本时,响应格式可能在 Spring Boot 2.0 及更早版本中有所不同,具体取决于内容协商(提供内容类型和接受头以获得最佳结果)。
参阅[测试功能应用程序]了解如何测试此类应用程序的详细信息和示例。
HTTP Request Parameters
正如你从上表中所看到的,你可以将参数作为路径变量传递给函数(即`/{function}/{item}`)。例如,http://localhost:8080/uppercase/foo`将调用`uppercase`函数,其输入参数为`foo
。
虽然这是推荐的方法,并且适合大多数用例,但有时你必须处理 HTTP 请求参数(例如`http://localhost:8080/uppercase/foo?name=Bill`)。框架会将 HTTP 请求参数像 HTTP 头一样对待,并将它们存储在`Message`头中,其头键为`http_request_param`,其值是请求参数的`Map`,因此为了访问它们,你的函数输入签名应该接受 Message
类型(例如`Function<Message<String>, String>`)。为了方便,我们提供`HeaderUtils.HTTP_REQUEST_PARAM`常量。
Function Mapping rules
如果目录中只有一个函数(消费者等),则路径中的名称是可选的。换句话说,只要你只在目录中有`uppercase`函数`curl -H "Content-Type: text/plain" localhost:8080/uppercase -d hello`和 `curl -H "Content-Type: text/plain" localhost:8080/ -d hello`调用是相同的。
复合函数可以使用管道或逗号来分离函数名来寻址(管道在 URL 路径中是合法的,但在命令行中输入起来有点别扭)。例如,curl -H "Content-Type: text/plain" localhost:8080/uppercase,reverse -d hello
。
当目录中有多个函数时,每个函数都会被导出并映射,其函数名是路径的一部分(例如,localhost:8080/uppercase
)。在这种情况下,你仍然可以通过提供`spring.cloud.function.definition`属性来将特定函数或函数组合映射到根路径。
例如,
--spring.cloud.function.definition=foo|bar
上面的属性将组合“foo”和“bar”函数,并将组合函数映射到“/”路径。
相同的属性也适用于无法通过 URL 解析函数的情况。例如,你的 URL 可能为`localhost:8080/uppercase`,但没有`uppercase`函数。但是有函数`foo`和`bar`。因此,在这种情况下,localhost:8080/uppercase`将解析为`foo|bar
。这对 URL 用于传达特定信息的情况尤其有用,因为会有一个名为`uri`的消息头,其值为实际 URL,使用户能够使用它进行评估和计算。
Function Filtering rules
在目录中有多个函数的情况下,可能需要仅导出某些函数或函数组合。在这种情况下,你可以使用相同的`spring.cloud.function.definition`属性列出你打算导出的函数,并用“;”分隔。请注意,在这种情况下,没有任何内容将映射到根路径,而未列出的函数(包括组合)将不会被导出
例如,
--spring.cloud.function.definition=foo;bar
无论目录中存在多少函数(例如,localhost:8080/foo
),都只会导出函数 foo
和函数 bar
。
--spring.cloud.function.definition=foo|bar;baz
无论目录中存在多少函数(例如,localhost:8080/foo,bar
),都只会导出函数组合 foo|bar
和函数 baz
。
Http Headers propagation
默认情况下,大多数请求 HttpHeaders
会复制到响应 HttpHeaders
中。如果你需要过滤掉某些标题,可以使用用逗号分隔的 spring.cloud.function.http.ignored-headers
提供那些标题的名称。例如,spring.cloud.function.http.ignored-headers=foo,bar
CRUD REST with Spring Cloud Function
现在应该很清楚,函数导出为 REST 端点,并且可以使用多种 HTTP 方法进行调用。换句话说,可以通过 GET、POST、PUT 等来触发单个函数。
然而,这并不总是理想的,肯定不适合 CRUD 概念。而且,虽然 SCF 不支持并且无意支持 Spring Web 堆栈的所有功能,但该框架确实为 CRUD 映射提供了支持,其中一个函数可以映射到特定的 HTTP 方法。它通过 spring.cloud.function.http.<method-name>
属性实现。
例如,
spring.cloud.function.http.GET=uppercase;reverse;foo|bar spring.cloud.function.http.POST=reverse spring.cloud.function.http.DELETE=deleteById
正如您所见,在这里,我们使用与 spring.cloud.function.definition
属性相同的规则(其中“;”允许我们定义多个函数,而“|”表示函数组合)将函数映射到各种 HTTP 方法。