找不到参数FromRequestUnmarshaller Akka的隐含值

时间:2017-12-15 00:53:44

标签: scala akka slick

我正在尝试为用户,位置和访问等对象创建此API。我希望有post方法来添加和更新这些对象的值。但是,我不知道如何将对象传递给api的路径。我的位置更新路线的一部分:

trait ApiRoute extends MyDatabases with FailFastCirceSupport {
     val routes =
          pathPrefix("locations") {
            pathSingleSlash {
              pathPrefix(LongNumber) { id =>
                  post { entity(as[Location]){
                    location => {
                      onSuccess(locationRepository.update(location)) {
                        result => complete(result.asJson)
                      }
                    }
                  }
}

然而,当我尝试以这种方式构建更新时,我收到错误:

could not find implicit value for parameter um: akka.http.scaladsl.unmarshalling.FromRequestUnmarshaller[models.Location]
[error]               post { entity(as[Location]){

Json编码器的位置:

package object application {
      implicit val locationEncoder = new Encoder[Location] {
        final def apply(location: Location): Json = Json.obj(
          ("id", Json.fromLong(location.id)),
          ("place", Json.fromString(location.place)),
          ("country", Json.fromString(location.country)),
          ("city", Json.fromString(location.city)),
          ("distance", Json.fromLong(location.distance))
        )
      }

我使用Slick建模并从数据库中获取所有数据:

case class Location (id: Long, place: String, country: String, city: String, distance: Long)

class LocationTable(tag: Tag) extends Table[Location](tag, "locations") {
  val id = column[Long]("id", O.PrimaryKey)
  val place = column[String]("place")
  val country = column[String]("country")
  val city = column[String]("city")
  val distance = column[Long]("distance")

  def * = (id, place, country, city, distance) <> (Location.apply _ tupled, Location.unapply)
}

object LocationTable {
  val table = TableQuery[LocationTable]
}

class LocationRepository(db: Database) {
  val locationTableQuery = TableQuery[LocationTable]

  def create(location: Location): Future[Location] =
    db.run(locationTableQuery returning locationTableQuery += location)

  def update(location: Location): Future[Int] =
    db.run(locationTableQuery.filter(_.id === location.id).update(location))
}

那么我应该在代码中添加或更改哪些内容以消除异常并使其正常工作?

1 个答案:

答案 0 :(得分:3)

如果要添加或更新位置,该位置还需要解码器,以便从作为HTTP实体的线路中的客户端读取序列化数据。 Akka HTTP还需要一个FromRequestUnmarshaller与解码器一起解码请求实体,在这个例子中是你要添加或更新的位置,以及你从中提取id的那个。

使用Scala's Circe library进行JSON处理,然后使用Akka HTTP JSON project has part of what you need。如该项目所示,将以下内容添加到build.sbt

// All releases including intermediate ones are published here,
// final ones are also published to Maven Central.
resolvers += Resolver.bintrayRepo("hseeberger", "maven")

libraryDependencies ++= List(
  "de.heikoseeberger" %% "akka-http-circe" % "1.18.0"
)

然后您可以使用FailFastCirceSupport或ErrorAccumulatingCirceSupport混合使用所需的支持。将其添加到使用

定义路径的类中
class SomeClassWithRoutes extends ErrorAccumulatingCirceSupport

class SomeClassWithRoutes extends FailFastCirceSupport

取决于您是否要在第一个错误上失败(如果有),或者累积它们。

您仍然需要在范围内设置解码器[位置]。为此您可以see Circe's documentation,但是如果您想要默认字段名称,可以快速定义一种方法是在路径定义类或文件中使用以下导入,以便Circe为您创建必要的解码器。

import io.circe.generic.auto._
import io.circe.Decoder