anchor.diff:  RouterFunction<ServerResponse> personRoute =
   	route(GET("/person/{id}").and(accept(APPLICATION_JSON)), handler::getPerson)
   		.andRoute(GET("/person").and(accept(APPLICATION_JSON)), handler::listPeople)
  -		.andRoute(POST("/person").and(contentType(APPLICATION_JSON)), handler::createPerson);
  -----
  -
  -Besides router functions, you can also compose request predicates, by calling
  -`RequestPredicate.and(RequestPredicate)` or `RequestPredicate.or(RequestPredicate)`.
  -These work as expected: for `and` the resulting predicate matches if *both* given predicates match;
  -`or` matches if *either* predicate does.
  -Most of the predicates found in `RequestPredicates` are compositions.
  -For instance, `RequestPredicates.GET(String)` is a composition of
  -`RequestPredicates.method(HttpMethod)` and `RequestPredicates.path(String)`.
  +		.andRoute(POST("/person"), handler::createPerson);
  +----
  +
   
   
   
  
positive.code: 
  
  
  [[webflux-fn-handler-functions]]
  == HandlerFunction
  
  Incoming HTTP requests are handled by a **`HandlerFunction`**, which is essentially a function that
  takes a `ServerRequest` and returns a `Mono<ServerResponse>`. If you're familiar with the
  annotation-based programming model, a handler function is the equivalent of an
  `@RequestMapping` method.
  
  `ServerRequest` and `ServerResponse` are immutable interfaces that offer JDK-8 friendly access
  to the underlying HTTP messages with http://www.reactive-streams.org[Reactive Streams]
  non-blocking back pressure. The request exposes the body as Reactor `Flux` or `Mono`
  types; the response accepts any Reactive Streams `Publisher` as body. The rational for this
  is explained in <<web-reactive.adoc#webflux-reactive-libraries,Reactive Libraries>>.
  
  `ServerRequest` gives access to various HTTP request elements:
  the method, URI, query parameters, and headers (via a separate `ServerRequest.Headers`
  interface. Access to the body is provided through the `body` methods. For instance, this is
  how to extract the request body into a `Mono<String>`:
  
   Mono<String> string = request.bodyToMono(String.class);
  
  And here is how to extract the body into a `Flux`, where `Person` is a class that can be
  deserialised from the contents of the body (i.e. `Person` is supported by Jackson if the body
  contains JSON, or JAXB if XML).
  
   Flux<Person> people = request.bodyToFlux(Person.class);
  
  The `bodyToMono` and `bodyToFlux` used above are in fact convenience methods that use the
  generic `ServerRequest.body(BodyExtractor)` method. `BodyExtractor` is
  a functional strategy interface that allows you to write your own extraction logic, but common
  `BodyExtractor` instances can be found in the `BodyExtractors` utility class. So, the above
  examples can also be written as follows:
  
   Mono<String> string = request.body(BodyExtractors.toMono(String.class);
   Flux<Person> people = request.body(BodyExtractors.toFlux(Person.class);
  
  Similarly, `ServerResponse` provides access to the HTTP response. Since it is immutable, you create
  a `ServerResponse` with a builder. The builder allows you to set the response status, add response
  headers, and provide a body. For instance, this is how to create a response with a 200 OK status,
  a JSON content-type, and a body:
  
   Mono<Person> person = ...
   ServerResponse.ok().contentType(MediaType.APPLICATION_JSON).body(person);
  
  And here is how to build a response with a 201 CREATED status, a `"Location"` header, and
  empty body:
  
   URI location = ...
   ServerResponse.created(location).build();
  
  
  Putting these together allows us to create a `HandlerFunction`. For instance, here is an example
  of a simple "Hello World" handler lambda, that returns a response with a 200 status and a body
  based on a String:
  
  [source,java,indent=0]
  [subs="verbatim,quotes"]
  
negative.code: [[webflux-fn-router-functions]]
  == RouterFunction
  
  `RouterFunction` is used to route requests to a `HandlerFunction`. Typically, you do not
  write router functions yourself, but rather use
  `RouterFunctions.route(RequestPredicate, HandlerFunction)`. If the predicate applies, the
  request is routed to the given `HandlerFunction`, or otherwise no routing is performed,
  and that would translate to a 404 (Not Found) response.
  
  
  
  [[webflux-fn-predicates]]
  === Predicates
  
  You can write your own `RequestPredicate`, but the `RequestPredicates` utility class
  offers commonly implementations, based on the request path, HTTP method, content-type,
  and so on. For example:
  
  [source,java,indent=0]
  [subs="verbatim,quotes"]
  ----
  RouterFunction<ServerResponse> route =
  	RouterFunctions.route(RequestPredicates.path("/hello-world"),
  	request -> Response.ok().body(fromObject("Hello World")));
  ----
  
  You can compose multiple request predicates together via:
  
  * `RequestPredicate.and(RequestPredicate)` -- both must match.
  * `RequestPredicate.or(RequestPredicate)` -- either may match.
  
  Many of the predicates from `RequestPredicates` are composed. For example
  `RequestPredicates.GET(String)` is composed from `RequestPredicates.method(HttpMethod)`
  and `RequestPredicates.path(String)`.
  
  You can compose multiple router functions into one, such that they're evaluated in order,
  and if the first route doesn't match, the second is evaluated. You can declare more
  specific routes before more general ones.
  
  
  
  [[webflux-fn-routes]]
  === Routes
  
  You can compose multiple router functions together via:
  
  * `RouterFunction.and(RouterFunction)`
  * `RouterFunction.andRoute(RequestPredicate, HandlerFunction)` -- shortcut for
  `RouterFunction.and()` with nested `RouterFunctions.route()`.
  
  Using composed routes and predicates, we can then declare the following routes, referring
  to methods in the `PersonHandler`, shown in <<webflux-fn-handler-class>>, through
  https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html[method-references]:
  
  [source,java,indent=0]
  [subs="verbatim,quotes"]
  