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 方法。