我正在尝试按照官方文档使用akka喷雾模块中的marshallers:
https://doc.akka.io/docs/akka-http/current/common/json-support.html
这对于使用类实例完成请求的路由都很有用,为此我定义了一个隐式JsonFormat。
但是对于返回的路线,让我们说一个单位,它不会编译时出现以下错误:
类型不匹配,预期:ToResponseMarshallable,实际未来[单位]
DELETE方法是删除资源并返回Unit的情况。在这种情况下,我想返回一个HttpResponse(status = StatusCodes.NoContent),但它没有编译,因为我混合了我的JsonMarshaller特征。
在文档中,我可以很容易地找到代码,只返回给定路径的完整方法中的HttpResponse而不在任何JsonMarshallers中混合或返回一个对象,我为此提供了一个JsonFormat,但我需要同时为不同的路线,我在文档中找不到。
以下是代码:
ProductsRouter.scala:
class ProductsRouter (implicit val context: ExecutionContext) extends JsonMarshaller {
val productService = new InMemoryProductService
val routes = pathPrefix("products") {
pathEnd {
get {
// GET /products
parameters(
'limit.as[Int] ? productService.defaultLimit,
'offset.as[Int] ? productService.defaultOffset) { (limit, offset) =>
complete(productService.getProducts(limit, offset))
}
} ~
post {
// POST /products
entity(as[ProductToCreate]) {
product =>
complete(productService.createProduct(product))
}
}
} ~ path(Segment) { productId: ProductId =>
get {
// GET /products/{id}
complete(productService.getProduct(productId))
} ~
delete {
// DELETE /products/{id}
complete(productService.deleteProduct(productId))
} ~
put {
// PUT /products/{id}
entity(as[Product]) {
product => complete(productService.updateProduct(product))
}
}
}
}
}
JsonMarshaller.scala
import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport
import spray.json._
import server.models.{Meal, Product, ProductId, ProductToCreate}
trait JsonMarshaller extends SprayJsonSupport with DefaultJsonProtocol {
implicit val productIdFormat = jsonFormat(ProductId, "id")
implicit val productFormat = jsonFormat5(Product)
implicit val productToCreateFormat = jsonFormat4(ProductToCreate)
}
除
之外的所有内容productService.deleteProduct(productId)
的工作原理。这种方法的签名是:
override def deleteProduct(id: ProductId): Future[Unit]
如何在保持JsonMarshaller特性混合的同时在完整方法中序列化HttpResponse?比如:
delete {
// DELETE /products/{id}
complete {
productService.deleteProduct(productId).flatmap(_ => HttpResponse(status = StatusCodes.NoContent)
}
}