You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Scala结合akka-http与MongoDB实现全量数据查询

Akka-HTTP + MongoDB 实现全量数据查询的CRUD路由

嘿,看你已经在写基于Scala、Akka-HTTP和MongoDB的CRUD服务了,现在要补充从MongoDB集合返回所有数据的功能对吧?我来帮你把这段路由代码完善起来!

首先,给Repository加个全量查询方法

你现在的Repository应该只有findById,得先新增一个findAll方法来从MongoDB获取所有数据:

// 假设你的Image模型和Repository定义如下
case class Image(id: String, name: String, url: String) {
  // 你的asResource方法,用来把实体转成响应格式(比如JSON)
  def asResource: // 这里填你的转换逻辑,比如用Circe转Json
}

trait ImageRepository {
  def findById(id: String): Future[Option[Image]]
  // 新增全量查询方法
  def findAll(): Future[Seq[Image]]
}

// MongoDB的Repository实现示例
class MongoImageRepository(collection: MongoCollection[Document]) extends ImageRepository {
  // 你已有的findById实现这里就不重复了
  
  override def findAll(): Future[Seq[Image]] = {
    collection.find().toFuture().map { mongoDocs =>
      // 把Mongo的Document转成你的Image实体
      mongoDocs.map { doc =>
        Image(
          doc.getString("_id"),
          doc.getString("name"),
          doc.getString("url")
        )
      }
    }
  }
}

然后修改Akka-HTTP路由,新增全量查询接口

在你现有的imageRoute里,用~把新的路由分支和原来的按ID查询分支组合起来,这样就能匹配GET /api/image(全量)和GET /api/image/{id}(单条)两个请求了:

val imageRoute = {
  pathPrefix("api") {
    pathPrefix("image") {
      // 新增:获取所有图片的接口
      get {
        pathEndOrSingleSlash { // 匹配/api/image 或者 /api/image/
          complete {
            repository.findAll()
              .map(images => images.map(_.asResource)) // 把所有实体转成响应格式
              .map(StatusCodes.OK -> _) // 返回200状态码+数据列表
              // 可选:加个异常处理,查询出错返回500
              .recover { case ex =>
                StatusCodes.InternalServerError -> s"查询失败:${ex.getMessage}"
              }
          }
        }
      } ~ // 用~连接多个路由分支,Akka-HTTP会按顺序匹配
      // 你原来的按ID查询的路由
      get {
        path(Segment).as(FindByIdRequest) { request =>
          complete {
            repository.findById(request.id)
              .map(_.map(_.asResource))
              .flatMap {
                case None => Future.successful(HttpResponse(status = StatusCodes.NotFound))
                case Some(resource) => Future.successful(HttpResponse(status = StatusCodes.OK, entity = resource))
              }
          }
        }
      }
    }
  }
}

几个要注意的小细节

  • 路由分支的顺序很重要,Akka-HTTP会从上到下匹配,所以把更具体的路由(带ID的)放在后面,避免被更宽泛的路由(全量)拦截
  • pathEndOrSingleSlash确保不管请求路径最后有没有斜杠都能匹配到
  • 记得你的asResource要能正确把Image转成Akka-HTTP能处理的HttpEntity,比如用Circe的话可以转成Json然后用asJson方法生成实体

这样你就可以通过GET /api/image请求拿到MongoDB集合里的所有数据啦!

内容的提问来源于stack exchange,提问作者Nespony

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:23:42