Direct access to the RequestContext
is rarely needed. In fact, you only need it if you want to write custom directives. Common tasks and extracting the usual bits of data can normally be handled using one of the predefined directives.
It seems what you want to do is manual content type negotiation. In fact, you don't have to do it manually as spray does content type automatically for common data structures. Your example can be shortened to
get {
complete("Hello World!")
}
When complete
is called with a string the response will always be of type text/plain
. If the client would send a request with an Accept
header that doesn't accept text/plain
the request would already be rejected by the server.
If you want to customize the kinds of content types that can be provided from a Scala data-type you need to provide a custom Marshaller. See the documentation on how to achieve that.
Answering your original question why adding context =>
makes the request timeout: This is because the predefined directives already are of type RequestContext => Unit
. So, writing
respondWithMediaType(`text/plain`) {
complete("Hello World!")
}
is exactly equivalent to (i.e. automatically expanded to)
ctx => respondWithMediaType(`text/plain`) {
complete("Hello World!")
}.apply(ctx)
So, if you add only ctx =>
manually, but don't add the apply
call, an incoming request is never fed into the inner route and therefore never completed. The compiler doesn't catch this kind of error because the type of a route is RequestContext => Unit
and so the variant with and the variant without the apply
invocation are both valid. We are going to improve this in the future.
See the documentation for more info about how routes are built.
Finally, if you need to extract a header or its value you can use one of the predefined HeaderDirectives that simplify working with request headers a lot.
respondWithMediaType
though, that is my interpretation :) – Worldlywise