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?
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.
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With