# Concepts It allows to dispatch HTTP responses very easily to different handler methods based on any characteristic of the response, including but not limited to status code, status family and content type. The way this works is intentionally very similar to server-side request routing where any request that reaches a web application is usually routed to the correct handler based on any combination of the following criteria: URI including query and path parameters, method, `Accept` and `Content-Type` header. Instead of routing requests to handler methods on the server what *Riptide* does is the exact opposite: routing responses to handler methods on the client side. ![Routing Tree](https://docs.google.com/drawings/d/1BRTXVtmwIMJti1l5cQMrZsfKnTfBElTB8pDSxVBQbIQ/pub?w=888&h=691) ### Route > A Route is either a user-supplied **callback or** a nested **[routing tree](#routing-tree)**. Following a route will execute the callback or traverse the routing tree respectively. ```java on(SUCCESSFUL).call(response -> System.out.println(response.getHeaders().getLocation())) ``` ### Routing Tree > A Routing Tree is a route that is represented as the combination of a **[navigator](#navigator) and** a set of **[bindings](#binding)**. ```java on(SUCCESSFUL).dispatch(contentType(), on(APPLICATION_JSON).call(..), on(APPLICATION_XML).call(..)) ``` ### Navigator > A Navigator **chooses among** the **[bindings](#binding)** of a [routing tree](#routing-tree). The act of **traversing a [routing tree](#routing-tree)** by choosing a binding and following its associated route is called **nested dispatch**. | Navigator | Aspect | |-----------------------------------------------------------------------------------------------------------|----------------------| | [Navigators.series()](../riptide-core/src/main/java/org/zalando/riptide/SeriesNavigator.java) | Class of status code | | [Navigators.status()](../riptide-core/src/main/java/org/zalando/riptide/StatusNavigator.java) | Status | | [Navigators.statusCode()](../riptide-core/src/main/java/org/zalando/riptide/StatusCodeNavigator.java) | Status code | | [Navigators.reasonPhrase()](../riptide-core/src/main/java/org/zalando/riptide/ReasonPhraseNavigator.java) | Reason Phrase | | [Navigators.contentType()](../riptide-core/src/main/java/org/zalando/riptide/ContentTypeNavigator.java) | Content-Type header | ### Binding > A Binding **binds an attribute to a [route](#route)**. It represents a choice to the [navigator](#navigator) which route to follow. | Route | Syntax | |----------------------------------------|-----------------------------------------------------| | `ThrowingRunnable` | `on(..).call(ThrowingRunnable)` | | `ThrowingConsumer` | `on(..).call(ThrowingConsumer)` | | `ThrowingConsumer` | `on(..).call(Class, ThrowingConsumer)` | | `ThrowingConsumer` | `on(..).call(TypeToken, ThrowingConsumer)` | | `RoutingTree` | `on(..).dispatch(..)` | ### Common Patterns #### Redirect routing — extracting a Location header A route is a callback over `ClientHttpResponse` or a decoded body. To inspect a response header, use `on(..).call(ThrowingConsumer)`: ```java http.get("/start") .dispatch(series(), on(REDIRECTION).call(response -> { URI next = response.getHeaders().getLocation(); // continue with next request or store URI })); ``` > **Note on automatic redirect following:** The Apache HTTP client (used by default) follows > redirects automatically, so a `3xx` response may never reach your routing callback unless you > disable redirect handling on the client. To observe `Location` headers yourself, configure > `HttpClientCustomizer` to call `builder.disableRedirectHandling()`. See > [riptide-example-basic](../riptide-example-basic) for a working example. #### Body deserialization To decode the response body into a typed object, pass the target class as the first argument: ```java http.get("/users/me") .dispatch(series(), on(SUCCESSFUL).call(User.class, user -> { // user is already deserialized })); ``` For a complete, runnable example with full imports — including both patterns above — see [riptide-example-basic](../riptide-example-basic).