Fintrospect is a library that adds an intelligent HTTP routing layer to the Finagle RPC framework from Twitter. It provides a simple way to implement contracts for both server and client-side HTTP services which are:
Type-safe: auto-marshalls all request parameters/bodies into the correct types (including primitives + JSON/XML etc...)
Auto-validating: the presence of required and optional request parameters and bodies are checked before entering service-layer code
Auto-documenting: runtime generation of endpoint documentation such as Swagger JSON or web sitemap XML. Generates JSON Schema for example object formats to be included in these API docs.
Uniform: reuse the same contract to define both incoming or outgoing Finagle HTTP services. This also allows extremely low effort fake servers to be created
Additionally, Fintrospect provides a number of mechanisms to leverage these routes:
- Easily build type-safe HTTP responses with a set of custom builders for a wide variety of message formats:
- Serve static content from the classpath or a directory
Viewsupport (with Hot-Reloading) for building responses with Mustache or Handlebars
- Anonymising headers for dynamic-path based endpoints, removing all dynamic path elements. This allows, for example, calls to particular endpoints to be grouped for metric purposes. e.g.
- Interacts seamlessly with other Finagle based libraries, such as Finagle OAuth2
- Utilities to help you unit-test endpoint services and write HTTP contract tests for remote dependencies
The main concepts in play:
RouteSpec: defines the self-describing contract of an HTTP endpoint
ServerRoute: the binding of a
RouteSpecto a Finagle
Serviceimplementing some business-logic, to create an inbound HTTP endpoint
RouteClient: the binding of a
RouteSpecto a Finagle
Servicerepresenting an HTTP client, to create a simple function for making outbound HTTP calls
ParameterSpec: defines the acceptable format for a request parameter (Path/Query/Header/Form-field). Provides the auto-marshalling mechanic for serializing and deserializing objects to and from HTTP messages
BodySpec: similar to
ParameterSpec, but applied to the body of an HTTP message
ModuleSpec: defines a set of
ServerRouteinstances which are grouped under a particular request path. These modules can be combined and then converted to a Finagle
Serviceand attached to a Finagle HTTP server. Each module provides an endpoint under which it's own runtime-generated documentation can be served (eg. in Swagger format)
ResponseSpec: defines the characteristics of a possible response generated by a
Since Fintrospect is build on top of Finagle, it's worth acquainting yourself with it's concepts, which can be found here.
&tldr; finagle primer
- Finagle provides protocol-agnostic RPC and is based on Netty
- It is mainly asynchronous and makes heavy usage of Twitter's version of Scala Futures
- It defines uniform
Filterinterfaces for both client and server APIs that are effectively a single method...
Service: def apply(request : Request) : Future[Response] Filter: def apply(request : RequestIn, service : Service[RequestOut, ResponseIn]) : Future[ResponseOut]
Filterscan be chained together and then applied to a
Service, which results in another
Service. This is useful to apply layers of functionality such as caching headers, retry behaviour, and timeouts.
a note on style
- The code in this guide has omitted imports that would have made the it read more concisely. The sacrifices we make in the name of learning... :)