liveBook · Manning

@destinationvariable

As explained in Spring in Action, Sixth Edition

@DestinationVariable is a Spring annotation that binds a handler-method parameter to a variable extracted from an RSocket route.

@DestinationVariable binds a handler-method parameter to a variable embedded in an RSocket route. A route such as greeting/{name} declares the name placeholder; the annotation extracts its value and passes it into the method, much like Spring MVC’s @PathVariable. section 14.2.1

Personalized request-response greeting

Use the same placeholder name in @MessageMapping and @DestinationVariable: @MessageMapping("greeting/{name}") public Mono<String> handleGreeting( @DestinationVariable("name") String name, Mono<String> greetingMono) { return greetingMono .doOnNext(greeting -> log.info("Received a greeting from {} : {}", name, greeting)) .map(greeting -> "Hello to you, too, " + name); } A client supplies the value while building its route: route("greeting/{name}", "Craig"). The handler can then use name in logging and in its response. section 14.2.1

@MessageMapping("greeting/{name}")
public Mono<String> handleGreeting(
        @DestinationVariable("name") String name, 
        Mono<String> greetingMono) {
    
    return greetingMono
        .doOnNext(greeting -> 
            log.info("Received a greeting from {} : {}", name, greeting))
        .map(greeting -> "Hello to you, too, " + name);
}

Inspect the complete handler signature showing the route placeholder and its matching annotated parameter. section 14.2.1

Variable binding in a request stream

The annotation also binds variables for streaming handlers. A route such as stock/{symbol} supplies the stock symbol to a method returning Flux<StockQuote>. The stream can then include that symbol in every generated quote, while the client calls route("stock/{symbol}", stockSymbol) and retrieves a Flux. section 14.2.2

Listing 14.5 An RSocket controller to stream stock quotes
package rsocket;
import java.math.BigDecimal;
import java.time.Duration;
import java.time.Instant;
 
import org.springframework.messaging.handler.annotation.DestinationVariable;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.stereotype.Controller;
 
import reactor.core.publisher.Flux;
 
@Controller
public class StockQuoteController {
    
    @MessageMapping("stock/{symbol}")
    public Flux<StockQuote> getStockPrice(
            @DestinationVariable("symbol") String symbol) {
        return Flux
            .interval(Duration.ofSeconds(1))
            .map(i -> {
                BigDecimal price = BigDecimal.valueOf(Math.random() * 10);
                return new StockQuote(symbol, price, Instant.now());
            });
    }
}

Inspect a complete streaming controller that binds symbol from stock/{symbol} and produces periodic StockQuote values. section 14.2.2

How Spring in Action, Sixth Edition covers it

How deep it goes
Explains placeholder matching and handler access, but does not detail annotation internals or advanced routing rules.
Examples
Uses personalized greetings and stock-quote streams to demonstrate route-variable extraction.
What it assumes
Assumes basic Spring controllers, @MessageMapping, RSocket routes, and reactive Mono or Flux handlers.
What you can do after
Apply route variables in RSocket controllers and supply their values through RSocketRequester routes.
How it connects
Connects RSocket routes with @MessageMapping, Spring MVC @PathVariable, Mono, Flux, and request-stream messaging.

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.