-
Notifications
You must be signed in to change notification settings - Fork 0
Custom Directives
sprays architecture makes the creation of custom directives really easy. When you look at the implementation of the existing directives you'll see that most of them are themselves put together from a rather limited set of low-level directives that implement the very basic directive operations "filtering" and "transforming".
For implementing a directive that filters requests based on some criterion and/or extracts some values you should use one the following directives as a basis:
filterfilter1filter2filter3filter4filter5filter6filter7filter8filter9
Each of these directives takes one argument of type RouteFilter, which is defined like this:
type RouteFilter[T <: Product] = RequestContext => FilterResult[T]There are only two types that implement a FilterResult: Reject and Pass. By returning either one or the other the
filter directive decides whether to reject the request or not. Should the RouteFilter function decide to let the
request pass it can optionally supply the Pass instance a number of extraction objects.
The number of extractions must be stable (i.e. independent from the request) and match the filter method the
RouteFilter is passed to. filter takes a RouteFilter that produces zero values, filter1 one that produces 1
value, and so on. There are no restrictions on the types of the extracted values, the filter infrastructure will make
sure that they are properly and type-safely passed to the inner function producing a Route.
As an example, here is a slightly simplified version of the method directive:
def method(m: HttpMethod) = filter { ctx =>
if (ctx.request.method == m) Pass() else Reject(MethodRejection(m))
}In addition to the extractions the Pass class can optionally be supplied with a custom RequestContext transformation
function, which allows you to combine "filtering" with "transforming".
Apart from filtering requests directives need a way to transform the incoming request, the outgoing response or both. Transforming requests can easily be created via the following built-in transformation directives:
transformRequesttransformResponsetransformRequestContexttransformRejectionstransformRoutetransformChunkedResponsetransformUnchunkedResponse
The most basic ones are transformRoute and transformRequestContext, the others are merely small specializations.
transformRoute applies a given Route => Route function to its inner route. This lets you wrap an inner route with
your own logic. For example, the cacheResults directive is written using transformRoute since it needs to be able
to explicitly run its inner route in the context of its own logic.
transformRequestContext is the most basic directive for all logic that does not explicitly need to reference its inner
route. It takes a RequestContext => RequestContext function as parameter and allows you to inject logic before and/or
after the inner route is run.
As examples, here are the implementation of two other transformation directives, which directly rely on
transformRequestContext:
def transformRequest(f: HttpRequest => HttpRequest) =
transformRequestContext(_.withRequestTransformed(f))
def transformResponse(f: HttpResponse => HttpResponse) =
transformRequestContext(_.withHttpResponseTransformed(f))For an example of a custom route that uses transformResponse you might want to take a look at the "markdown-server"
example (see the Example Projects chapter), which transforms responses with the custom media type text/x-markdown
to text/html.
- Home
- Requirements
- spray-server
- ... Getting Started
- ... Key Concepts
- ...... Request Lifecycle
- ...... Routes
- ...... Directives
- ...... Composing Directives
- ...... Rejections
- ...... Marshalling and Unmarshalling
- ... Predefined Directives
- ...... Method Filters
- ...... Path Filters
- ...... Parameter Filters
- ...... Form-Field Filters
- ...... Marshalling/Unmarshalling
- ...... Caching
- ...... Detach
- ...... Encoding/Decoding
- ...... Authentication/Authorization
- ...... File and Resource Directives
- ...... Misc Directives
- ... Advanced Topics
- ...... Case Class Extraction
- ...... Custom Directives
- ...... Custom Media Types
- ...... Custom Error Responses
- ... Configuration
- ... Testing
- ... Example Projects
- spray-client
- Patch Policy
- Credits
- Sponsors