Search code examples
scalarestsprayspray-dsl

How to structure a RESTful API with Spray.io?


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


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)     
          }        
        }
      }