跳到主要内容

独立 Web 应用程序

DeepSeek V3 中英对照 Standalone Web Applications

函数可以自动导出为 HTTP 端点。

spring-cloud-function-web 模块具有自动配置功能,当它被包含在支持 MVC 的 Spring Boot Web 应用程序中时,该功能会自动激活。此外,还有一个 spring-cloud-starter-function-web 模块,用于收集所有可选的依赖项,以便您能够获得简单的入门体验。

激活 Web 配置后,您的应用程序将拥有一个 MVC 端点(默认在 "/" 路径下,但可以通过 spring.cloud.function.web.path 进行配置),该端点可用于访问应用程序上下文中的函数,其中函数名称将成为 URL 路径的一部分。支持的内容类型为纯文本和 JSON。

important

重要的是要理解,虽然 SCF 提供了将功能 Bean 导出为 REST 端点的能力,但它并不是 Spring MVC/WebFlux 等的替代品。它主要是为了适应无状态的无服务器模式,在这种模式下,你只是希望通过 HTTP 暴露一些无状态的功能。

方法路径请求响应状态
GET/{supplier}-来自指定供应商的项目200 OK
POST/{consumer}JSON 对象或文本镜像输入并将请求体推送到消费者202 Accepted
PUT/{consumer}JSON 对象或文本镜像输入并将请求体推送到消费者202 Accepted
DELETE/{consumer}JSON 对象或文本-204 NO CONTENT
POST/{function}JSON 对象或文本应用指定函数的结果200 OK
PUT/{function}JSON 对象或文本应用指定函数的结果200 OK
GET/{function}/{item}-将项目转换为对象并返回应用函数的结果200 OK

如上表所示,端点的行为取决于方法以及传入请求数据的类型。当传入的数据是单值,并且目标函数被声明为明显单值(即不返回集合或 Flux)时,响应也将包含单个值。对于多值响应,客户端可以通过发送 Accept: text/event-stream 来请求服务器发送事件流。

使用 Message<?> 声明输入和输出的函数和消费者会将请求头视为消息头,并且输出的消息头将被转换为 HTTP 头。消息的有效载荷(payload)将是一个 body,如果没有 body 或它为 null,则为一个空字符串。

在 Spring Boot 2.0 及更早版本中,POST 文本时的响应格式可能会有所不同,具体取决于内容协商(提供内容类型和接受标头以获得最佳结果)。

请参见[测试功能应用程序]以了解如何测试此类应用程序的详细信息和示例。

HTTP 请求参数

正如你从之前的表格中注意到的,你可以将参数作为路径变量传递给函数(即 /{function}/{item})。例如,[localhost:8080/uppercase/foo](http://localhost:8080/uppercase/foo) 将导致调用 uppercase 函数,其输入参数为 foo

虽然这是推荐的方法并且适用于大多数用例,但有时你必须处理 HTTP 请求参数(例如,[localhost:8080/uppercase/foo?name=Bill](http://localhost:8080/uppercase/foo?name=Bill))。框架会将 HTTP 请求参数类似于 HTTP 头进行处理,将它们存储在 Message 头中的 http_request_param 头键下,其值为请求参数的 Map,因此为了访问它们,你的函数输入签名应接受 Message 类型(例如,Function<Message<String>, String>)。为了方便起见,我们提供了 HeaderUtils.HTTP_REQUEST_PARAM 常量。

函数映射规则

如果目录中只有一个函数(如消费者等),路径中的名称是可选的。换句话说,如果你在目录中只有 uppercase 函数,那么 curl -H "Content-Type: text/plain" localhost:8080/uppercase -d hellocurl -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

上述属性将组合 foobar 函数,并将组合后的函数映射到 "/" 路径。

同样的属性也适用于无法通过 URL 解析函数的情况。例如,你的 URL 可能是 localhost:8080/uppercase,但并没有 uppercase 函数。然而,存在函数 foobar。因此,在这种情况下,localhost:8080/uppercase 将解析为 foo|bar。这在 URL 用于传递某些信息时尤其有用,因为会有一个名为 uri 的消息头,其值为实际的 URL,使用户能够利用它进行评估和计算。

函数过滤规则

在目录中存在多个函数的情况下,可能需要仅导出某些函数或函数组合。在这种情况下,你可以使用相同的 spring.cloud.function.definition 属性,列出你打算导出的函数,并用 ; 分隔。请注意,在这种情况下,不会将任何内容映射到根路径,并且未列出的函数(包括组合)将不会被导出。

例如,

--spring.cloud.function.definition=foo;bar

这将仅导出函数 foo 和函数 bar,无论目录中有多少函数可用(例如,localhost:8080/foo)。

--spring.cloud.function.definition=foo|bar;baz

这将仅导出函数组合 foo|bar 和函数 baz,无论目录中有多少函数可用(例如,localhost:8080/foo,bar)。

HTTP 头信息传播

默认情况下,大多数请求的 HttpHeaders 会被复制到响应的 HttpHeaders 中。如果你需要过滤掉某些特定的头信息,可以通过 spring.cloud.function.http.ignored-headers 提供这些头信息的名称,并用逗号分隔。例如,spring.cloud.function.http.ignored-headers=foo,bar

使用 Spring Cloud Function 实现 CRUD REST

到目前为止,应该清楚的是,函数是作为 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 方法,其中“;”允许我们定义多个函数,而“|”表示函数组合。