Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spray client - treat response with unexpected content-type as application/json?

When I try to GET amazon identity data like that

val pipeline: HttpRequest => Future[IdentityData] = sendReceive ~> unmarshal[IdentityData]
pipeline(Get("http://169.254.169.254/latest/dynamic/instance-identity/document"))

with appropriate case class and formatter, I receive the following exception

UnsupportedContentType(Expected 'application/json')

because amazon mark their response as text/plain content type. They also don't care about the Accept header param. Is there an easy way to tell spray-json to ignore this on unmarshalling?

like image 633
eugen-fried Avatar asked Jan 10 '23 07:01

eugen-fried


2 Answers

After digging in spray mail list I wrote a function that works

def mapTextPlainToApplicationJson: HttpResponse => HttpResponse = {
  case r@ HttpResponse(_, entity, _, _) =>
    r.withEntity(entity.flatMap(amazonEntity => HttpEntity(ContentType(MediaTypes.`application/json`), amazonEntity.data)))
  case x => x
}

and the used it in the pipeline

val pipeline: HttpRequest => Future[IdentityData] = sendReceive ~> mapTextPlainToApplicationJson ~> unmarshal[IdentityData]
pipeline(Get("http://169.254.169.254/latest/dynamic/instance-identity/document"))

The cool thing is here you can intercept & alter any HttpResponse as long as your intercepting function has the appropriate signature.

like image 73
eugen-fried Avatar answered Jan 17 '23 14:01

eugen-fried


If you want to extract some IdentityData (which is a case class with a defined jsonFormat) from amazon response, which is a valid json, but with text/plain context type you can simply extract text data, parse it a json and convert into your data, e.g:

entity.asString.parseJson.convertTo(identityDataJsonFormat)
like image 22
4lex1v Avatar answered Jan 17 '23 15:01

4lex1v