Quantcast
Channel: Akka Libraries - Discussion Forum for Akka technologies
Viewing all articles
Browse latest Browse all 1367

Debugging Akka Http and Slick

$
0
0

Hi folks,

I’m quite new to Scala and am working on an Akka Http REST API that connects to a Postgres database via Slick.

Basically, the routes should ask the categoryRepository actor to request a list of Categories from the CategoriesDao, which uses Slick to query the database.

CategoriesDao and categoryRepository should respond with a Seq[Category] which is then mapped to a List[Category] in the route, which should complete as JSON.

I figure somewhere along the way I am providing an incompatible value, or not handling a Future correctly but the compiler isn’t complaining. The code is compiling but then responding to GET requests with a 500 error.

Does anyone have advice on how I should go about debugging this?

The various parts are:

//CategoryRoutes.scala
import scala.concurrent._
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport._
import spray.json.DefaultJsonProtocol._
import akka.util.Timeout
import akka.pattern.ask
import com.foram.models.{Category, Categories}
import com.foram.actors.CategoryRepository._
import com.foram.Main.{categoryRepository}
import scala.concurrent.duration._

class CategoryRoutes {
  import com.foram.JsonFormats._
  implicit val timeout = Timeout(2 seconds)

  val categoryRoutes =
    pathPrefix("api" / "categories") {
      get {
          path(IntNumber) { id =>
            complete((categoryRepository ? GetCategoryByID(id)).mapTo[Option[Category]])
          } ~
          pathEndOrSingleSlash {
            complete((categoryRepository ? GetAllCategories).mapTo[List[Category]])
          }
      }
    }
}
// CategoryRepository.scala
import scala.concurrent.ExecutionContext.Implicits.global
import akka.actor.{Actor, ActorLogging, Props}
import com.foram.dao.CategoriesDao
import com.foram.models.{Category, Categories}
import scala.util.{Failure, Success}

object CategoryRepository {
  case class ActionPerformed(action: String)
  case object GetAllCategories
  case class GetCategoryByID(id: Int)
  case class CreateCategory(category: Category)
  case class UpdateCategory(id: Int, category: Category)
  case class DeleteCategory(id: Int)
  case object OperationSuccess
  def props = Props[CategoryRepository]
}

class CategoryRepository extends Actor with ActorLogging {
  import CategoryRepository._

  override def receive: Receive = {
    case GetAllCategories =>
      println(s"CategoryRepositoryActor Searching for categories")
      val allCategories = CategoriesDao.findAll
      allCategories.onComplete {
        case Success(categories) => sender() ! Categories(categories)
        case Failure(failure) => println("Data not found")
      }

    case GetCategoryByID(id) =>
      println(s"Finding category with id: $id")
      val category = CategoriesDao.findById(id)
      category.onComplete {
        case Success(category) => sender() ! category
        case Failure(failure) => println(s"$id category not found")
      }

    case CreateCategory(category) =>
      println(s"Creating category $category")
      CategoriesDao.create(category)
      sender() ! ActionPerformed(s"Category ${category.name} created.")

    // TODO
    //    case UpdateCategory(id, category) =>
    //      log.info(s"Updating category $category")
    //      categories = categories + (id -> category)
    //      sender() ! OperationSuccess

    case DeleteCategory(id) =>
      println(s"Removing category id $id")
      val category = CategoriesDao.delete(id)
      category.onComplete {
        case Success(category) => sender() ! ActionPerformed(s"Category $id deleted")
        case Failure(failure) => println(s"Unable to delete category $id")
      }
  }
}
// CategoriesDAO.scala
import com.foram.models.Category
import slick.jdbc.PostgresProfile.api._
import scala.concurrent.Future

object CategoriesDao extends BaseDao {
  def findAll: Future[Seq[Category]] = db.run(categories.result)
  def findById(id: Int): Future[Category] = db.run(categories.filter(_.id === id).result.head)
  def create(category: Category) = categories.returning(categories.map(_.id)) += category
  def delete(id: Int) = db.run(categories.filter(_.id === id).delete)
}

I would be very grateful for any debugging advice anyone can offer.

The full source code is available in this GitHub repo.

1 post - 1 participant

Read full topic


Viewing all articles
Browse latest Browse all 1367

Trending Articles