required: spray.httpx.marshalling.ToResponseMarshallable Error

五迷三道 提交于 2019-12-07 10:53:27

You'll need to define how a Post will be serialized, which you can do via a spray-json Protocol (see the docs for more detailed information). It's quite easy to do so, but before that, you'll also need to define a format for the BSONObjectId type, since there's no built-in support for that type in spray-json (alternatively, if object_id is a string representation of the BSONObjectId, think about removing the id property from your Post class or change it to be a String):

// necessary imports
import spray.json._
import spray.httpx.SprayJsonSupport._

implicit object BSONObjectIdProtocol extends RootJsonFormat[BSONObjectID] {
    override def write(obj: BSONObjectID): JsValue = JsString(obj.stringify)
    override def read(json: JsValue): BSONObjectID = json match {
      case JsString(id) => BSONObjectID.parse(id) match {
        case Success(validId) => validId
        case _ => deserializationError("Invalid BSON Object Id")
      }
      case _ => deserializationError("BSON Object Id expected")
    }
}

Now, we're able to define the actual protocol for the Post class:

object PostJsonProtocol extends DefaultJsonProtocol {
    implicit val format = jsonFormat5(Post.apply)
}

Furthermore, we'll also need to make sure that we have the defined format in scope:

import PostJsonProtocol._

Now, everything will compile as expected.

One more thing: have a look at the docs about the DSL structure of spray. Your mongoService.getAll() isn't within a complete block, which might not reflect your intentions. This ain't an issue yet, but probably will be if your route get more complex. To fix this issue simply put the future into the onComplete call or make it lazy:

val route1 =
  path("posts") {
    onComplete(mongoService.getAll()) {
      case Success(value) => complete(value)
      case Failure(ex)    => complete(ex.getMessage)
    }
  } 
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!