[英]How to unmarshall json response removing unnecessary fields using Akka HTTP
I'm new to Akka HTTP and I want to get rid of unnecessary fields from a JSON response and take only the necessary fields.我是 Akka HTTP 的新手,我想从 JSON 响应中删除不必要的字段,只取必要的字段。 For example, I use this endpoint to get the response and it contains a bunch of fields.例如,我使用这个端点来获取响应,它包含一堆字段。 For the moment I only need 'name' and 'versions'.目前我只需要“名称”和“版本”。 I would like to know how to deserialize this into a case class containing only 'name' and 'versions'.我想知道如何将其反序列化为仅包含“名称”和“版本”的案例 class。 I coded the following lines to get the response as a string.我对以下几行进行了编码以将响应作为字符串获取。
import akka.http.scaladsl.Http
import akka.http.scaladsl.model.{HttpRequest, HttpResponse}
import akka.stream.scaladsl.{Flow, Sink, Source}
import akka.stream.{ActorMaterializer, OverflowStrategy}
import scala.concurrent.Future
import scala.concurrent.duration.DurationInt
import scala.language.postfixOps
import scala.util.{Failure, Success}
object SoftwareRegistry extends App {
implicit val system = ActorSystem("NPMRegistry")
implicit val materializer = ActorMaterializer()
import system.dispatcher
case class NPMPackage(name: String)
// reading the packages
val filename = "B:\\Scala\\NPMRegistry\\src\\main\\resources\\packages.txt"
val bufferedSource = scala.io.Source.fromFile(filename)
val listOfPackages: List[NPMPackage] = (for (line <- bufferedSource.getLines) yield {
NPMPackage(line.trim)
}).toList
bufferedSource.close()
// source
val sourceList = Source(listOfPackages)
// sink
val sink = Sink.foreach[NPMPackage] { p =>
// https request
val responseFuture: Future[HttpResponse] =
Http().singleRequest(HttpRequest(uri = s"https://registry.npmjs.org/${p.name}"))
val x = responseFuture
.flatMap(_.entity.toStrict(2 seconds))
.map(_.data.utf8String)
x.onComplete {
case Success(res) => println(res)
case Failure(_) => sys.error("Something went wrong")
}
}
// flow to slow things down and streaming sink to time-delayed operations
val bufferedFlow = Flow[NPMPackage]
.buffer(10, overflowStrategy = OverflowStrategy.backpressure)
.throttle(1, 3 seconds)
sourceList.async
.via(bufferedFlow).async
.to(sink)
.run()
}
For parsing json
you need to use some library.要解析json
您需要使用一些库。 In akka-http
docs they use spray-json
.在akka-http
文档中,他们使用spray-json
。 Add the following dependency to your build.sbt
with appropriate akkaHttpVersion
.使用适当的akkaHttpVersion
将以下依赖项添加到您的build.sbt
中。
"com.typesafe.akka" %% "akka-http-spray-json" % akkaHttpVersion
Now you need serializers and deserializers for your data.现在您的数据需要序列化器和反序列化器。 I am using a simple model, change it as needed.我使用的是简单的 model,根据需要进行更改。
trait Formatter extends DefaultJsonProtocol {
implicit object jsonFormat extends JsonFormat[Versions] {
override def read(json: JsValue): Versions = json match {
case JsObject(fields) =>
Versions(fields.keys.toList)
}
override def write(obj: Versions): JsValue = JsonParser(obj.toString)
}
implicit val formatterPackage: RootJsonFormat[Package] = jsonFormat2(Package)
case class Package(name: String, versions: Versions)
case class Versions(versions: List[String])
}
Finally sink
:最后sink
:
val sink = Sink.foreach[NPMPackage] { p =>
// https request
val responseFuture: Future[HttpResponse] =
Http().singleRequest(HttpRequest(uri = s"https://registry.npmjs.org/${p.name}"))
val packages = responseFuture
.flatMap(
_.entity
.dataBytes
.via(JsonFraming.objectScanner(Int.MaxValue))
.map(_.utf8String)
.map(_.parseJson.convertTo[Package])
.toMat(Sink.seq)(Keep.right)
.run()
)
packages.onComplete {
case Success(res) => println(res)
case Failure(_) => sys.error("Something went wrong")
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.