Convert Consumer<Foo> to Function<Flux<Foo>,Mono<Void>>

This results in a better experience for users because the consumer
that they write is only applied to a Flux that is subscribed to
by the framework once. It gives better control over the flow of
foos, e.g. if some component wants to subscribe on a thread.
This commit is contained in:
Dave Syer
2018-03-26 10:06:13 +01:00
parent a1b624b28a
commit 5aeba1ea96
13 changed files with 144 additions and 76 deletions

View File

@@ -19,6 +19,53 @@ include::https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/maste
include::getting-started.adoc[]
== Function Catalog and Flexible Function Signatures
One of the main features of Spring Cloud Function is to adapt and
support a range of type signatures for user-defined functions. So
users can supply a bean of type `Function<String,String>`, for
instance, and the `FunctionCatalog` will wrap it into a
`Function<Flux<String>,Flux<String>>`. Users don't normally have to
care about the `FunctionCatalog` at all, but it is useful to know what
kind of functions are supported in user code.
Generally speaking users can expect that if they write a function for
a plain old Java type (or primitive wrapper), then the function
catalog will wrap it to a `Flux` of the same type. If the user writes
a function using `Message` (from spring-messaging) it will receive and
transmit headers from any adapter that supports key-value metadata
(e.g. HTTP headers). Here are the details.
|===
| User Function | Catalog Registration |
| `Function<S,T>` | `Function<Flux<S>, Flux<T>>` |
| `Function<Message<S>,Message<T>>` | `Function<Flux<Message<S>>, Flux<Message<T>>>` |
| `Function<Flux<S>, Flux<T>>` | `Function<Flux<S>, Flux<T>>` (pass through) |
| `Supplier<T>` | `Supplier<Flux<T>>` |
| `Supplier<Flux<T>>` | `Supplier<Flux<T>>` |
| `Consumer<T>` | `Function<Flux<T>, Mono<Void>>` |
| `Consumer<Message<T>>` | `Function<Flux<Message<T>>, Mono<Void>>` |
| `Consumer<Flux<T>>` | `Consumer<Flux<T>>` |
Consumer is a little bit special because it has a `void` return type,
which implies blocking, at least potentially. Most likely you will not
need to write `Consumer<Flux<?>>`, but if you do need to do that,
remember to subscribe to the input flux. If you declare a `Consumer`
of a non publisher type (which is normal), it will be converted to a
function that returns a publisher, so that it can be subscribed to in
a controlled way.
A function catalog can contain a `Supplier` and a `Function` (or
`Consumer`) with the same name (like a GET and a POST to the same
resource). It can even contain a `Consumer<Flux<>>` with the same name
as a `Function`, but it cannot contain a `Consumer<T>` and a
`Function<T,S>` with the same name when `T` is not a `Publisher`
because the consumer would be converted to a `Function` and only one
of them can be registered.
|===
== Standalone Web Applications
The `spring-cloud-function-web` module has autoconfiguration that