title: Akka HTTP Routing and Marshaling
body: <p>I'm just starting out with Akka HTTP and I'm having a bit of trouble with the routing DSL and marshaling. The tilde in the 'route' setup results in the error: </p>
  
  <blockquote>
    <p>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 ~'?</p>
  </blockquote>
  
  <p>Also, the JSON marshaling in the 'get' clause causing the error:</p>
  
  <blockquote>
    <p>◾Cannot find JsonWriter or JsonFormat type class for
    scala.collection.immutable.Map[String,scala.collection.mutable.Map[String,Tweet]] </p>
    
    <p>◾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.</p>
  </blockquote>
  
  <p>I've followed the documentation examples fairly closely, so I'd appreciate help in understanding these errors and how to resolve them. Thanks. </p>
  
  <p><strong>API</strong></p>
  
  <pre><code>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 &amp; entity(as[Tweet])) { tweet =&gt;
          complete {
            Created -&gt; Map("id" -&gt; TweetDb.save(tweet)).toJson
          }
        } ~ 
        (get) {
          complete {
            OK -&gt; Map("tweets" -&gt; 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 { _ =&gt; system.shutdown() }
  }
  </code></pre>
  
  <p><strong>Protocol</strong></p>
  
  <pre><code>import spray.json.DefaultJsonProtocol
  
  case class Tweet(author: String, body: String)
  
  object TweetProtocol extends DefaultJsonProtocol {
    implicit val TweetFormat = jsonFormat2(Tweet.apply)
  }
  </code></pre>
  
  <p><strong>Pseudo-database</strong></p>
  
  <pre><code>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 -&gt; tweet)
      id
    }
  
    def find() = tweets
  
    def findById(id: String) = tweets.get(id)
  }
  </code></pre>