简体   繁体   English

处理和操作 http 响应列表

[英]Handling and manipulating a list of http responses

I'm currently trying to implement API logic to fetch multiple images from a server.我目前正在尝试实现 API 逻辑以从服务器获取多个图像。 This server accepts an image id and return an HTTP response that contains the image in PNG format as an entity.此服务器接受图像 ID 并返回 HTTP 响应,其中包含 PNG 格式的图像作为实体。

Right now, we want to add a new endpoint that accepts a list of images IDs and return a list of all the images:现在,我们要添加一个新的端点,它接受图像 ID 列表并返回所有图像的列表:

I have done the following:我做了以下事情:

  def getImagesFromIds(IdsList: List[String]): Future[List[HttpResponse]] = {
    Future.sequence {
      IdsList.map(
        id => getImageById(id)
      )
    }
  }

this function will receive a list of ids and will call the getImageById to fetch all the images, it will return a list of HttpResponse.这个 function 将收到一个 id 列表,并将调用 getImageById 来获取所有图像,它将返回一个 HttpResponse 列表。

And for the route definition, I have done the following:对于路线定义,我做了以下工作:

  def getImagesByIdsListRoute: Route = get {
    path("by-ids-list") {
      entity(as[List[String]]){
        upcs =>
          complete(getImagesFromIds(upcs))
      }
    }
  }

But I'm getting the following error message:但我收到以下错误消息:

no implicits found for parameter m: marshalling.toresponsemarshallable[list[httpresponse]]没有找到参数 m 的隐式:marshalling.toresponsemarshallable[list[httpresponse]]

Does Any one know how we can marshall a list of http responses, or if there is any way to improve this logic to fetch multiple http responses?有没有人知道我们如何编组 http 响应列表,或者是否有任何方法可以改进此逻辑以获取多个 http 响应?

If I understand correctly, you want to download multiple images and return them as a HTTP response.如果我理解正确的话,你想要下载多张图片并将它们作为 HTTP 响应返回。

The problems with your current attempt您当前尝试的问题

  1. The call to the API made via getImageById returns a HttpResponse .通过getImageById调用 API 返回一个HttpResponse You can't be sure what is the result of this API call.您无法确定这个 API 调用的结果是什么。 If it fails, the response won't contain any image at all.如果失败,响应将根本不包含任何图像。
  2. You are trying to return List[HttpResponse] as your response.您正在尝试返回List[HttpResponse]作为您的响应。 How should this response be serialized?这个响应应该如何序列化? Akka doesn't know what you mean by that and tries to find a marshaller which will serialize your object (for example to JSON) but can't find one. Akka 不知道你的意思,并试图找到一个将序列化你的 object (例如到 JSON)但找不到的编组器。
  3. Returning a list of images requires zipping them.返回图像列表需要压缩它们。 You can't return multiple entities in a single HTTP response.您不能在单个 HTTP 响应中返回多个实体。

Possible approach可能的方法

  1. You have to change getImageById so that it checks what is in the HttpResponse and returns the entity bytes.您必须更改getImageById以便它检查HttpResponse中的内容并返回实体字节。

Example:例子:

response match {
  case HttpResponse(StatusCodes.OK, _, entity, _) =>
    entity.dataBytes
  case resp @ HttpResponse(code, _, _, _) =>
    // Response failed and we don't care about the response entity
    // Details: https://doc.akka.io/docs/akka-http/current/implications-of-streaming-http-entity.html
    resp.discardEntityBytes()
    // Decide yourself how you want to handle failures
    throw new RuntimeException("Request failed, response code: " + code)
}
  1. dataBytes returns a Source so you'll end up with a List of Sources . dataBytes返回一个Source所以你最终会得到一个List of Sources You have to concatenate them via, for example via concat .您必须通过连接它们,例如通过concat
  2. The result stream has to be zipped via Compression.gzip .结果 stream 必须通过Compression.gzip
  3. Finally, the stream can be put in the complete method of getImagesByIdsListRoute .最后,可以将 stream 放入getImagesByIdsListRoutecomplete方法中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM