shambalaxx
2/22/2017 - 5:55 AM

reading params

reading params

package main

import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.common.{NameDefaultReceptacle, NameOptionReceptacle, NameReceptacle}
import akka.http.scaladsl.model.Uri.Path
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.server.Route
import akka.stream.ActorMaterializer

object ApiRun extends Api with App {
  implicit val system = ActorSystem("my-system")
  implicit val materializer = ActorMaterializer()

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

trait Api {

  case class Param[T](name: String, opt: Boolean = true, default: Option[T] = None)

  abstract case class View(url: String) {
    def pathRoute = get & path(url)

    def route: Route

    def params: Product
    def paramsAsUrl = params.productIterator.toList.map {
      case r: NameOptionReceptacle[_]  => r.name
      case r: NameDefaultReceptacle[_] => s"${r.name}=${r.default}"
      case r: NameReceptacle[_]        => s"${r.name}=required"
      case param                       => s"$param=required"
    }.mkString("&")
  }

  val hello = new View("hello") {
    val params = ("one".as[Int], "two" ? 100, "three")
    val route: Route = pathRoute {
      parameters(params) { (a, b, c) =>
        complete(s"$a, $b, $c")
      }
    }
  }

  val test = new View("test") {
    val params = ("test1", "test2")
    val route: Route = (pathRoute & parameters(params)) { (a, b) =>
      complete("test method")
    }
  }

  val views = Seq(hello, test)

  val route = {
    views.map(_.route).reduceLeft((a, b) => a ~ b) ~ path("help") {
      get {
        extractUri { uri =>
          complete {
            views.map { v =>
              uri.withPath(Path("/" + v.url)).withRawQueryString(v.paramsAsUrl).toString()
            }.mkString("\n")
          }
        }
      }
    }
  }

}