liveBook · Manning

Request-response API

As explained in Spring in Action, Sixth Edition

A request-response model is a communication pattern in which one party sends a request and waits for a corresponding response.

A request-response API lets a client send one request and receive one corresponding response. HTTP and REST commonly use this pattern. RSocket supports it too, but handles the exchange with nonblocking, reactive types: the client still awaits a reply without tying up a thread while it waits. section 14.0 section 14.1

Choose request-response when one reply is what the client needs. If a request should produce many values, RSocket offers request-stream; if it needs no reply, fire-and-forget; if both sides need to keep sending data, a channel. section 14.1

To make a request-response exchange in Spring:

  • Add the Spring Boot RSocket starter and configure a server port, such as 7000. section 14.2 section 14.2.1
  • Handle a route with a controller method annotated @MessageMapping. A Mono<String> can carry the incoming value and the single reply. section 14.2.1
  • Build an RSocketRequester, select the route, supply the payload, and call retrieveMono(String.class). Subscribe to handle the returned value. section 14.2.1

A greeting exchange

A client sends “Hello RSocket!” to the greeting route. The controller returns “Hello back to you!” as a Mono<String>; the client subscribes to that Mono and logs the reply. A route such as greeting/{name} can also take a value supplied by the client. section 14.2.1

Listing 14.2 A simple RSocket request-response server
package rsocket;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.stereotype.Controller;
import lombok.extern.slf4j.Slf4j;
import reactor.core.publisher.Mono;
 
@Controller
@Slf4j
public class GreetingController {
 
    @MessageMapping("greeting")
    public Mono<String> handleGreeting(Mono<String> greetingMono) {
        return greetingMono
            .doOnNext(greeting -> 
                log.info("Received a greeting: {}", greeting))
            .map(greeting -> "Hello back to you!");
    }
    
}

The server listing shows how @MessageMapping connects the greeting route to a handler that turns one incoming greeting into one reply. section 14.2.1

Listing 14.3 Sending a request from a client
RSocketRequester tcp = requesterBuilder.tcp("localhost", 7000);
 
// ... send messages with RSocketRequester ...
tcp
  .route("greeting")
  .data("Hello RSocket!")
  .retrieveMono(String.class)
  .subscribe(response -> log.info("Got a response: {}", response));

The client listing shows the matching route, payload, retrieveMono call, and subscription in one exchange. section 14.2.1

How Spring in Action, Sixth Edition covers it

How deep it goes
Defines the exchange and works through a Spring server and client, including routing, payloads, response retrieval, and subscription.
Examples
Uses a greeting controller and an RSocketRequester that sends “Hello RSocket!” and logs the returned greeting.
What it assumes
Introduces RSocket's communication models and demonstrates Spring setup; uses Reactor's Mono and Spring controller and configuration annotations.
What you can do after
Apply it via Spring RSocket controllers and RSocketRequester to send a routed request and handle one reactive reply.
How it connects
Relates request-response to HTTP, REST, RSocket, reactive streams, request-stream, fire-and-forget, and channels.

Also explained in

Compare how 2 books explain request-response API →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Spring in Action, Sixth Edition. The section links point to the parts of the book it draws on.