Standalone Web Applications
函数可以自动导出为 HTTP 终结点。
Functions could be automatically exported as HTTP endpoints.
`spring-cloud-function-web`模块有自动配置,当它包含在 Spring Boot Web 应用程序中时激活(带有 MVC 支持)。还有一个`spring-cloud-starter-function-web`来收集所有可选的依赖项,以防你只想要一个简单的入门体验。
The spring-cloud-function-web
module has autoconfiguration that
activates when it is included in a Spring Boot web application (with
MVC support). There is also a spring-cloud-starter-function-web
to
collect all the optional dependencies in case you just want a simple
getting started experience.
通过激活 Web 配置,你的应用程序将有一个 MVC 终结点(默认为“/”,但可以用`spring.cloud.function.web.path`配置),它可以用来访问应用程序上下文中函数,函数名成为 URL 路径的一部分。支持的内容类型是纯文本和 JSON。
With the web configurations activated your app will have an MVC
endpoint (on "/" by default, but configurable with
spring.cloud.function.web.path
) that can be used to access the
functions in the application context where function name becomes part of the URL path. The supported content types are
plain text and JSON.
重要的是要明白,虽然 SCF 提供了将函数式 Bean 导出为 REST 端点的能力,但它并不是 Spring MVC/WebFlux 等的替代品。它主要是为了适应_stateless serverless patterns_,在这种情况下,您只想让一些无状态功能通过 HTTP 暴露。
It is important to understand that while SCF provides ability to export Functional beans as REST endpoints it is NOT a replacement for Spring MVC/WebFlux etc. It is primarily to accommodate stateless serverless patterns where you simply want to have some stateless functionality to be exposed via HTTP.
Method | Path | Request | Response | Status |
---|---|---|---|---|
GET |
/{supplier} |
- |
Items from the named supplier |
200 OK |
POST |
/{consumer} |
JSON object or text |
Mirrors input and pushes request body into consumer |
202 Accepted |
PUT |
/{consumer} |
JSON object or text |
Mirrors input and pushes request body into consumer |
202 Accepted |
DELETE |
/{consumer} |
JSON object or text |
- |
204 NO CONTENT |
POST |
/{function} |
JSON object or text |
The result of applying the named function |
200 OK |
PUT |
/{function} |
JSON object or text |
The result of applying the named function |
200 OK |
GET |
/{function}/{item} |
- |
Convert the item into an object and return the result of applying the function |
200 OK |
如上表所示,终结点行为取决于方法和传入请求数据类型。当传入数据单值时,而目标函数被显然声明为单值(即不返回集合或`Flux`),则响应也将包含一个单值。对于多值响应,客户端可以通过发送 Accept: text/event-stream
来请求服务器发送事件流。
As the table above shows the behavior of the endpoint depends on the method and also the type of incoming request data. When the incoming data is single valued, and the target function is declared as obviously single valued (i.e. not returning a collection or Flux
), then the response will also contain a single value.
For multi-valued responses the client can ask for a server-sent event stream by sending Accept: text/event-stream
.
`Message<?>`中输入和输出声明的函数和消费者会将请求头视为_消息头_,而输出_消息头_将被转换为 HTTP 头。消息的_有效负载_将是`body`或空字符串(如果没有_body_或它为 null)。
Functions and consumers that are declared with input and output in Message<?>
will see the request headers as message headers, and the output message headers will be converted to HTTP headers.
The payload of the Message will be a body
or empty string if there is no body
or it is null.
当发布文本时,响应格式可能在 Spring Boot 2.0 及更早版本中有所不同,具体取决于内容协商(提供内容类型和接受头以获得最佳结果)。
When POSTing text the response format might be different with Spring Boot 2.0 and older versions, depending on the content negotiation (provide content type and accept headers for the best results).
参阅[测试功能应用程序]了解如何测试此类应用程序的详细信息和示例。
See [Testing Functional Applications] to see the details and example on how to test such application.
HTTP Request Parameters
正如你从上表中所看到的,你可以将参数作为路径变量传递给函数(即`/{function}/{item}`)。例如,http://localhost:8080/uppercase/foo`将调用`uppercase`函数,其输入参数为`foo
。
As you have noticed from the previous table, you can pass an argument to a function as path variable (i.e., /{function}/{item}
).
For example, http://localhost:8080/uppercase/foo
will result in calling uppercase
function with its input parameter being 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`常量。
While this is the recommended approach and the one that fits most use cases cases, there are times when you have to deal with HTTP request parameters (e.g., http://localhost:8080/uppercase/foo?name=Bill
)
The framework will treat HTTP request parameters similar to the HTTP headers by storing them in the Message
headers under the header key http_request_param
with its value being a Map
of request parameters, so in order to access them your function input signature should accept Message
type (e.g., Function<Message<String>, String>
). For convenience we provide HeaderUtils.HTTP_REQUEST_PARAM
constant.
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`调用是相同的。
If there is only a single function (consumer etc.) in the catalog, the name in the path is optional.
In other words, providing you only have uppercase
function in catalog
curl -H "Content-Type: text/plain" localhost:8080/uppercase -d hello
and curl -H "Content-Type: text/plain" localhost:8080/ -d hello
calls are identical.
复合函数可以使用管道或逗号来分离函数名来寻址(管道在 URL 路径中是合法的,但在命令行中输入起来有点别扭)。例如,curl -H "Content-Type: text/plain" localhost:8080/uppercase,reverse -d hello
。
Composite functions can be addressed using pipes or commas to separate function names (pipes are legal in URL paths, but a bit awkward to type on the command line).
For example, curl -H "Content-Type: text/plain" localhost:8080/uppercase,reverse -d hello
.
当目录中有多个函数时,每个函数都会被导出并映射,其函数名是路径的一部分(例如,localhost:8080/uppercase
)。在这种情况下,你仍然可以通过提供`spring.cloud.function.definition`属性来将特定函数或函数组合映射到根路径。
For cases where there is more than a single function in catalog, each function will be exported and mapped with function name being
part of the path (e.g., localhost:8080/uppercase
).
In this scenario you can still map specific function or function composition to the root path by providing
spring.cloud.function.definition
property
例如,
For example,
--spring.cloud.function.definition=foo|bar
上面的属性将组合“foo”和“bar”函数,并将组合函数映射到“/”路径。
The above property will compose 'foo' and 'bar' function and map the composed function to the "/" path.
相同的属性也适用于无法通过 URL 解析函数的情况。例如,你的 URL 可能为`localhost:8080/uppercase`,但没有`uppercase`函数。但是有函数`foo`和`bar`。因此,在这种情况下,localhost:8080/uppercase`将解析为`foo|bar
。这对 URL 用于传达特定信息的情况尤其有用,因为会有一个名为`uri`的消息头,其值为实际 URL,使用户能够使用它进行评估和计算。
The same property will also work for cases where function can not be resolved via URL. For example, your URL may be localhost:8080/uppercase
, but there is no uppercase
function.
However there are function foo
and bar
. So, in this case localhost:8080/uppercase
will resolve to foo|bar
.
This could be useful especially for cases when URL is used to communicate certain information since there will be Message header called uri
with the value
of the actual URL, giving user ability to use it for evaluation and computation.
Function Filtering rules
在目录中有多个函数的情况下,可能需要仅导出某些函数或函数组合。在这种情况下,你可以使用相同的`spring.cloud.function.definition`属性列出你打算导出的函数,并用“;”分隔。请注意,在这种情况下,没有任何内容将映射到根路径,而未列出的函数(包括组合)将不会被导出
In situations where there are more than one function in catalog there may be a need to only export certain functions or function compositions. In that case you can use
the same spring.cloud.function.definition
property listing functions you intend to export delimited by ;
.
Note that in this case nothing will be mapped to the root path and functions that are not listed (including compositions) are not going to be exported
例如,
For example,
--spring.cloud.function.definition=foo;bar
无论目录中存在多少函数(例如,localhost:8080/foo
),都只会导出函数 foo
和函数 bar
。
This will only export function foo
and function bar
regardless how many functions are available in catalog (e.g., localhost:8080/foo
).
--spring.cloud.function.definition=foo|bar;baz
无论目录中存在多少函数(例如,localhost:8080/foo,bar
),都只会导出函数组合 foo|bar
和函数 baz
。
This will only export function composition foo|bar
and function baz
regardless how many functions are available in catalog (e.g., localhost:8080/foo,bar
).
Http Headers propagation
默认情况下,大多数请求 HttpHeaders
会复制到响应 HttpHeaders
中。如果你需要过滤掉某些标题,可以使用用逗号分隔的 spring.cloud.function.http.ignored-headers
提供那些标题的名称。例如,spring.cloud.function.http.ignored-headers=foo,bar
By default most request HttpHeaders
are copied into the response HttpHeaders
. If you require to filter out certain headers you can provide the names of those headers using
spring.cloud.function.http.ignored-headers
delimited by comas. For example, spring.cloud.function.http.ignored-headers=foo,bar
CRUD REST with Spring Cloud Function
现在应该很清楚,函数导出为 REST 端点,并且可以使用多种 HTTP 方法进行调用。换句话说,可以通过 GET、POST、PUT 等来触发单个函数。
By now it should be clear that functions are exported as REST endpoints and can be invoked using various HTTP methods. In other words a single function could be triggered via GET, POST, PUT etc.
然而,这并不总是理想的,肯定不适合 CRUD 概念。而且,虽然 SCF 不支持并且无意支持 Spring Web 堆栈的所有功能,但该框架确实为 CRUD 映射提供了支持,其中一个函数可以映射到特定的 HTTP 方法。它通过 spring.cloud.function.http.<method-name>
属性实现。
However, it is not always desirable and certainly does not fit the CRUD concept. And while SCF does not support and has no intention of supporting all the features of Spring web stack, the framework does provide support for CRUD mappings where a single function could be mapped to a particular HTTP method(s). It is done via spring.cloud.function.http.<method-name> property.
例如,
For example,
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 方法。
As you can see, here we’re mapping functions to various HTTP methods using the same rules as spring.cloud.function.definition
property where “;” allows us to define several functions and “|” signifies function composition.