-
Notifications
You must be signed in to change notification settings - Fork 0
Directives
"Directives" are small building blocks of which you can construct arbitrarily complex route structures. This is a simple example of a route built from directives:
val route: Route =
path("order" / HexIntNumber) { id =>
get {
completeWith {
"Received GET request for order " + id
}
} ~
put {
completeWith {
"Received PUT request for order " + id
}
}
}The general anatomy of a directive is as follows:
name(arguments) { extractions =>
... // inner route
}It has a name, zero or more arguments and optionally an inner route. Additionally directives can "extract" a number of
values and make them available to their inner routes. When seen "from the outside" a directive is an expression of type
Route.
A directive does one or more of the following:
- Transform the incoming RequestContext before passing it on to its inner route
- Filter the RequestContext according to some logic, i.e. only pass on certain requests and reject all others
- Apply some logic to the incoming RequestContext and create objects that are made available to inner routes as "extractions"
- Complete the request
The first point deserves some more discussion. A RequestContext is the central object that is passed on through a route structure and in between actors. It's immutable but light-weight and can therefore be copied quickly. When a directive receives a RequestContext instance from the outside it can decide to pass this instance on unchanged to its inner route or it can create a copy of the RequestContext instance, with one or more changes, and pass on this copy to its inner route. Typically this is good for two things:
- Transforming the HttpRequest instance
- "Hooking in" another HttpResponse transformation function into the responder function chain.
For understanding the latter point it is helpful to look at what happens when, in the inner-most route of a route
structure, the complete method of a RequestContext instance is called.
Consider the following hypothetical route structure of three nested directives around a simple route.
foo {
bar {
baz {
completeWith {
"Hello"
}
}
}
}Assume that foo and baz hook in response transformation logic whereas bar leaves the responder function of the
RequestContext that it receives unchanged before passing it on to its inner route. This is what happens when the
complete("Hello") call in the innermost route is issued:
- The
completemethod invokes theresponderfunction of the RequestContext. - The response transformation logic supplied by the
bazdirective runs and eventually invokes theresponderfunction of the RequestContext thebazdirective received. - The response transformation logic supplied by the
foodirective runs and eventually invokes theresponderfunction of the RequestContext thefoodirective received. - The responder logic of the original RequestContext is run, which writes out the response and resumes the suspended request.
As you can see all response handling logic forms a function chain that directives can choose to "hook into".
- 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