Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 931
Carlos Melo Avatar asked May 15 '14 21:05

Carlos Melo


People also ask

What is a RESTful API example?

A RESTful web service request contains: An Endpoint URL. An application implementing a RESTful API will define one or more URL endpoints with a domain, port, path, and/or query string — for example, https://mydomain/user/123?format=json .

What is simple REST API?

RESTful API is an interface that two computer systems use to exchange information securely over the internet. Most business applications have to communicate with other internal and third-party applications to perform various tasks.


1 Answers

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)     
      }        
    }
  }  
like image 163
Gangstead Avatar answered Oct 04 '22 10:10

Gangstead