I think you can do what you want by using the handleRejections combination explicitly with mapResponse . First, consider this simple route definition:
(get & path("foo")){ complete((StatusCodes.OK, HttpEntity(ContentTypes.`application/json`, """{"foo": "bar"}""" ))) }
If I get the corresponding request, I will respond using json and my caller will be happy because they will be able to parse the response as json. But if you try to call this endpoint with a POST request, you will get the answer as follows:
HTTP 405 Method Not Allowed Date: Wed, 06 Jan 2016 13:19:27 GMT Content-Type: text/plain; charset=UTF-8 Content-Length: 47 Allow: GET Server: akka-http/2.3.12 HTTP method not allowed, supported methods: GET
So here we get a simple text response that is undesirable. We can solve this problem everywhere by adding a couple of directives to the very top of my routing tree:
mapResponse(wrapToJson){ handleRejections(RejectionHandler.default){ (get & path("foo")){ complete((StatusCodes.OK, HttpEntity(ContentTypes.`application/json`, """{"foo": "bar"}""" ))) } } }
With wrapToJson is defined as:
def wrapToJson(resp:HttpResponse):HttpResponse = { //If we get a text/plain response entity, remap it otherwise do nothing val newResp = resp.entity match{ case HttpEntity.Strict(ContentTypes.`text/plain(UTF-8)` , content ) => val jsonResp = s"""{"error": "${content.utf8String}"}""" resp.copy(entity = HttpEntity(ContentTypes.`application/json`, jsonResp)) case other => resp } newResp }
This is a very simple example, and you will probably have a better way to generate json, but it just shows how you can fix the plan text responses from the default reject handler. Now you must explicitly mapResponse default deviation handler in mapResponse , because automatic processing is added beyond the top level of any tree you define, and thus mapResponse will not see deviation cases. You still get the default processing, but through RejectionHandler.default .
Hope this is close to what you were.