How to structure a RESTful API with Spray.io?

rest, scala, spray, spray-dsl

Solution

You can certainly forward requests from one actor to another, based on paths or whatever else. Check out my example project (which is a fork of a fork of an example project):

https://github.com/gangstead/spray-moviedb/blob/master/src/main/scala/com/example/routes/ApiRouter.scala

Relavent code from the main actor that receives all requests and routes them to other actors that handle each service:

  def receive = runRoute {
    compressResponseIfRequested(){
      alwaysCache(simpleCache) {
        pathPrefix("movies") { ctx => asb.moviesRoute ! ctx } ~
        pathPrefix("people") { ctx => asb.peopleRoute ! ctx }
      } ~
      pathPrefix("login") { ctx => asb.loginRoute ! ctx } ~
      pathPrefix("account") { ctx => asb.accountRoute ! ctx }
    }
  }

And for example the movies route:

  def receive = runRoute {
    get {
      parameters('query, 'page ? 1).as(TitleSearchQuery) { query =>
        val titleSearchResults = ms.getTitleSearchResults(query)
        complete(titleSearchResults) 
      }~
      path(LongNumber) { movieId =>  
        val movie = ms.getMovie(movieId)
        complete(movie)
      }~
      path(LongNumber / "cast") { movieId =>
        val movieCast = ms.getMovieCast(movieId)
        complete(movieCast)      
      }~
      path(LongNumber / "trailers") { movieId =>
        val trailers = ms.getTrailers(movieId)
        complete(trailers)     
      }        
    }
  }  

Problem

When I'm using Spray.io to develop a RESTful API, how should I structure my application? I already saw this answer on how to split a Spray application, but I'm not satisfied with it, since it doesn't seem to use the "one actor per request" approach. Can I forward requests from the root actor to other actors in my application based on paths and, inside these actors, define the related routes? Thanks

Original source

Related problems