/ / Decode JSON gzippé dans Akka HTTP - json, scala, akka-http

Décodez le JSON gzippé dans Akka HTTP - json, scala, akka-http

J'ai un point final que nous pouvons appeler /test qui récupère en interne les données d'une API tierceet veut ensuite faire une transformation avant de retourner une réponse. Lorsque je suis suspendu, cette API tierce retourne un fichier JSON compressé et je ne peux pas le décoder (pour le moment). J'ai trouvé le directive decodeRequest mais il semble que je dois utiliser cela dans mon routage et je suis un niveau plus profond ici. J'ai une méthode interne que j'appelle une fois que je reçois un GET à mon point final /test qui est nommé do3rdPartyAPIRequest où je construis un HttpRequest et passer à Http().singleRequest() alors en retour j'ai un Future[HttpResponse] qui est où je pense que je veux être mais je suis coincé ici.

Avec certaines API locales que j’ai construites et consommées de la même manière, je n’ai pas encodé mes réponses de manière typique. Future[HttpResponse] Je vérifie l'état de la réponse et passe à la conversion en JSON via Unmarshal mais celui-ci nécessite une étape supplémentaire à ma connaissance avant de passer à JSON. Je me rends compte que cette question est très similaire à celui-là Cependant, cela est spécifique à la pulvérisation et je n'ai pas été en mesure de traduire cette réponse en http: akka

Réponses:

6 pour la réponse № 1

Enfin compris cela - ce n'est peut-être pas le meilleur moyen d'obtenir un bytestring de la réponse, mais cela fonctionne .. Il s'avère que vous pouvez utiliser Classe Gzip

et vous avez deux options

  1. Gzip.decode
  2. Gzip.decoderFlow

Voici mes exemples au cas où cela vous aiderait:

def getMyDomainObject(resp: HttpResponse):Future[MyDomain] = {
for {
byteString <- resp.entity.dataBytes.runFold(ByteString(""))(_ ++ _)
decompressedBytes <- Gzip.decode(byteString)
result <- Unmarshal(decompressedBytes).to[MyDomain]
} yield result
}


def getMyDomainObjectVersion2(resp:HttpResponse):Future[MyDomain] = {
resp.entity.dataBytes
.via(Gzip.decoderFlow)
.runWith(Sink.head)
.flatMap(Unmarshal(_).to[MyDomain])
}

2 pour la réponse № 2

Vous vous attendriez à ce que le contenu compressé soit géré par défaut par akka-http, mais il ne fournit que PredefinedFromEntityUnmarshallers et à l'intérieur de l'entité il n'y a pas d'informations sur Content-encoding entête.

Pour résoudre ce problème, vous devez implémenter votre propre Unmarshaller et en tenir compte.

Exemple:

implicit val gzipMessageUnmarshaller = Unmarshaller(ec => {
(msg: HttpMessage) => {
val `content-encoding` = msg.getHeader("Content-Encoding")
if (`content-encoding`.isPresent && `content-encoding`.get().value() == "gzip") {
val decompressedResponse = msg.entity.transformDataBytes(Gzip.decoderFlow)
Unmarshal(decompressedResponse).to[String]
} else {
Unmarshal(msg).to[String]
}
}
})