2016-03-30 114 views
2

我剛剛開始使用Akka HTTP,並且在路由DSL和封送處理時遇到了一些問題。在錯誤的「路徑」設置結果代字號:Akka HTTP路由和封送

value ~ is not a member of akka.http.scaladsl.server.RequestContext ⇒ scala.concurrent.Future[akka.http.scaladsl.server.RouteResult] possible cause: maybe a semicolon is missing before 'value ~'?

此外,JSON編組的「得到」子句中導致錯誤:

◾Cannot find JsonWriter or JsonFormat type class for scala.collection.immutable.Map[String,scala.collection.mutable.Map[String,Tweet]]

◾not enough arguments for method toJson: (implicit writer: spray.json.JsonWriter[scala.collection.immutable.Map[String,scala.collection> .mutable.Map[String,Tweet]]])spray.json.JsValue. Unspecified value parameter writer.

我已經按照文檔的例子相當密切合作,所以我希望能幫助您理解這些錯誤以及如何解決這些錯誤。謝謝。

API

import akka.actor.ActorSystem 
import scala.concurrent.Future 
import akka.stream.ActorMaterializer 
import akka.http.scaladsl.Http 
import akka.http.scaladsl.server.Directives.path 
import akka.http.scaladsl.server.Directives.pathPrefix 
import akka.http.scaladsl.server.Directives.post 
import akka.http.scaladsl.server.Directives.get 
import akka.http.scaladsl.server.Directives.complete 
import akka.http.scaladsl.unmarshalling.Unmarshal 
import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport._ 
import akka.http.scaladsl.server.Directives.{entity, as} 
import akka.http.scaladsl.model.StatusCodes.{Created, OK} 
import spray.json._ 
import DefaultJsonProtocol._ 
import akka.stream.Materializer 
import scala.concurrent.ExecutionContext 

trait RestApi { 
    import TweetProtocol._ 
    import TweetDb._ 

    implicit val system: ActorSystem 
    implicit val materializer: Materializer 
    implicit val execCtx: ExecutionContext 

    val route = 
    pathPrefix("tweets") { 
     (post & entity(as[Tweet])) { tweet => 
     complete { 
      Created -> Map("id" -> TweetDb.save(tweet)).toJson 
     } 
     } ~ 
     (get) { 
     complete { 
      OK -> Map("tweets" -> TweetDb.find()).toJson 
     } 
     } 
    } 
} 

object TweetApi extends App with RestApi { 
    implicit val system = ActorSystem("webapi") 
    implicit val materializer = ActorMaterializer() 
    implicit val execCtx = system.dispatcher 

    val bindingFuture = Http().bindAndHandle(route, "localhost", 8080) 

    println(s"Server online at http://localhost:8080/\nPress RETURN to stop...") 
    Console.readLine() 

    bindingFuture.flatMap(_.unbind()).onComplete { _ => system.shutdown() } 
} 

協議

import spray.json.DefaultJsonProtocol 

case class Tweet(author: String, body: String) 

object TweetProtocol extends DefaultJsonProtocol { 
    implicit val TweetFormat = jsonFormat2(Tweet.apply) 
} 

僞數據庫

import scala.collection.mutable.Map 

object TweetDb { 
    private var tweets = Map[String, Tweet]() 

    def save(tweet: Tweet) = { 
    val id: String = java.util.UUID.randomUUID().toString() 
    tweets += (id -> tweet) 
    id 
    } 

    def find() = tweets 

    def findById(id: String) = tweets.get(id) 
} 
+3

您可以通過導入'import akka.http.scaladsl.server.Directives._'而不是從'Directives'導入這些單獨的導入來解決一個問題。我想有一些implicits在那裏,當你導入所有東西並且啓用'〜'運算符時會被導入。 – cmbaxter

回答

2

爲了您的第一個錯誤,請嘗試蘇從評論中獲取,即。進口全部來自指令

對於第二部分

◾Cannot find JsonWriter or JsonFormat type class for scala.collection.immutable.Map[String,scala.collection.mutable.Map[String,Tweet]]

◾not enough arguments for method toJson: (implicit writer: spray.json.JsonWriter[scala.collection.immutable.Map[String,scala.collection> .mutable.Map[String,Tweet]]])spray.json.JsValue. Unspecified value parameter writer.

您需要定義JsonFormat爲Map[String, mutable.Map[String, Tweet]]

通過在您TweetProtocol創建對象,擴展RootJsonFormat 如。

type DBEntry = Map[String, mutable.Map[String, Tweet]] 
object TweetProtocol extends DefaultJsonProtocol { 
    implicit object DBEntryJsonFormat extends RootJsonFormat[DBEntry] { 
    override def read(json: JSValue) { 
     // your implementation 
    } 
    override def write(dbEntry: DBEntry) { 
     // implementation 
    } 
    } 
} 
+0

我有同樣的錯誤:「值〜不是akka.http.scaladsl.server.Route的成員」。 – Readren