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.
A Route is either a user-supplied callback or a nested routing tree. Following a route will execute the callback or traverse the routing tree respectively.
on(SUCCESSFUL).call(response ->
System.out.println(response.getHeaders().getLocation()))
A Routing Tree is a route that is represented as the combination of a navigator and a set of bindings.
on(SUCCESSFUL).dispatch(contentType(),
on(APPLICATION_JSON).call(..),
on(APPLICATION_XML).call(..))
A Navigator chooses among the bindings of a routing tree. The act of traversing a routing tree by choosing a binding and following its associated route is called nested dispatch.
Navigator | Aspect |
---|---|
Navigators.series() | Class of status code |
Navigators.status() | Status |
Navigators.statusCode() | Status code |
Navigators.reasonPhrase() | Reason Phrase |
Navigators.contentType() | Content-Type header |
A Binding binds an attribute to a route. It represents a choice to the navigator which route to follow.
Route | Syntax |
---|---|
ThrowingRunnable |
on(..).call(ThrowingRunnable) |
ThrowingConsumer<ClientHttpResponse> |
on(..).call(ThrowingConsumer<ClientHttpResponse>) |
ThrowingConsumer<T> |
on(..).call(Class<T>, ThrowingConsumer<T>) |
ThrowingConsumer<T> |
on(..).call(TypeToken<T>, ThrowingConsumer<T>) |
RoutingTree |
on(..).dispatch(..) |