Hi,
Making first steps and trying to build a simple API mostly to learn & explore.
Sorry for long copy-pastes.
Using akka-http 2, Scala 2.11.7, Slick 3.01
Given:
1. I have a model "model.prices" with a getTotals() method that is supposed to return just one number (Int) back to the router (i.e. main page here with routes definition):
package com.myproject.model
import slick.driver.MySQLDriver.api._
import scala.concurrent.Await
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration._
import scala.concurrent.Future
object prices {
def getTotals(): Unit = {
val db = Database.forConfig("mysql1")
val timeout = 20.seconds
val q = sql"SELECT count(*) as total FROM prices".as[String]
val f: Future[Seq[String]] = db.run(q)
f.onSuccess { case s => println(s"Result: $s") }
f.onFailure { case s => -1 }
// Await.result(
// db.run(q).map { res =>
// // res is a Vector[String]
// println(res)
// }, timeout
// )
}
}
So in the end I have a Future (and as you see - tried Await.result too). Not sure how to send it back. Just printing w/o problems for now.
2. In the main file I have a route, that's supposed to receive result from that model:
package com.myproject
// importing this for a package object
import akka.actor.ActorSystem
import akka.http.scaladsl.model._
import akka.http.scaladsl.Http
import akka.http.scaladsl.unmarshalling.FromRequestUnmarshaller
import akka.http.scaladsl.server.Directives._
import akka.stream.ActorMaterializer
import scala.io.StdIn.readLine
import StatusCodes._
import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport
import spray.json._
import spray.json.DefaultJsonProtocol._
import model.prices
object main extends App with SprayJsonSupport {
implicit val system = ActorSystem()
implicit val materializer = ActorMaterializer()
implicit val ec = system.dispatcher
val route =
path("hello") {
get {
println(prices.getTotals())
val strout = "trying to get a result from model.prices".toJson
complete(strout)
}
} ~
complete(StatusCodes.NotFound, "Not found")
val bindingFuture = Http().bindAndHandle(route, "localhost", 8080)
println(s"Server online at http://localhost:8080/\nPress RETURN to stop...")
readLine() // for the future transformations
bindingFuture
.flatMap(_.unbind()) // trigger unbinding from the port
.onComplete(_ ⇒ system.terminate()) // and shutdown when done
}
Cannot wrap my head around the following:
1. How to receive an Int, not Future, result from a model that operates with a Future inside it?
2. Would not it be architecturally more correct for my service/model to actually return a Future, and for the controller to "unwrap" it?
3. ... maybe this should be question #1 in fact: do we need Future here at all?? If not, what would be my steps then?
Thank you!
D.