scala - How to generically wrap a Rejection with Akka-Http -
i use akka http routing system, along rejection system need nest response json rejection within generic json message block.
i have working in non-generic manner creating rejectionhandler adding cases possible rejections , handling them specific response code , message.
example:
// wraps string control block format def wrappingblock(msg: string) = ??? val myrejectionhandler = rejectionhandler .newbuilder() .handle{case malformedrequestcontentrejection(msg, detail) => complete(badrequest, wrappingblock(msg)) } ... // further lines other possible rejections ... // along response codes , messages. ... // nice if generic code ... // rather specific every rejection type. .result() val routes = handlerejections(myrejectionhandler){ ... } however, response code akka http provides default , pretty print message provided, nested within json control wrapper without line every possible rejection type. seems should possible have not been able complete it.
i think it's possible want using combination of handlerejections explicitly mapresponse. first, consider simple route definition:
(get & path("foo")){ complete((statuscodes.ok, httpentity(contenttypes.`application/json`, """{"foo": "bar"}""" ))) } if matching request respond using json , caller happy because can parse response json. if try , call endpoint post request, response 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: server: akka-http/2.3.12 http method not allowed, supported methods: so here plain text response not desirable. can solve problem universally adding couple of directives top of routing tree so:
mapresponse(wraptojson){ handlerejections(rejectionhandler.default){ (get & path("foo")){ complete((statuscodes.ok, httpentity(contenttypes.`application/json`, """{"foo": "bar"}""" ))) } } } with wraptojson being defined as:
def wraptojson(resp:httpresponse):httpresponse = { //if text/plain response entity, remap otherwise 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 basic example, , you'd probable have better way generating json, serves show how can fix plan text responses default rejection handler. now, must nest default rejection handler under mapresponse explicitly because automatic handling gets added outside top level of whatever tree define , mapresponse not see rejection cases. still default handling though via rejectionhandler.default.
hopefully close after.
Comments
Post a Comment