Skip to content

Instantly share code, notes, and snippets.

@davidmweber
Last active August 29, 2015 14:02
Show Gist options
  • Save davidmweber/14779c46dceb6bd15f8c to your computer and use it in GitHub Desktop.
Save davidmweber/14779c46dceb6bd15f8c to your computer and use it in GitHub Desktop.
Using Spray to compose routes for different API versions
package test
import spray.routing.Directives._
import org.scalatest.{Matchers, FunSpec}
import spray.testkit.ScalatestRouteTest
/**
* Routes that we can compose into our overall ReST API. The current plan
* is to have route completion in a separate compilation unit to keep the
* API layout easy to reason about.
*/
// API versions are layered as traits
trait RestV1_0 {
lazy protected val user = path("user") {
complete("user")
}
lazy protected val topicSearch = path("topicsearch" / Segment) { foo => complete(foo)}
lazy protected val routeV1_0 = pathPrefix("v1_0") {
get {
user ~ topicSearch
}
}
}
// V1.1 simply extends v1.0, adds another call and retains the old calls
trait RestV1_1 extends RestV1_0 {
lazy protected val geolocate = path("geolocate") {
complete("geolocate")
}
lazy protected val routeV1_1 = pathPrefix("v1_1") {
get {
user ~ topicSearch ~ geolocate
}
}
}
// Manifest the routes here as /api/v1_1 and /api/v1_0
object VersionedRoute extends RestV1_1 {
lazy val route = pathPrefix("api") {
routeV1_1 ~ routeV1_0
}
}
class RestRoutingTest extends FunSpec with ScalatestRouteTest with Matchers {
describe("Composed API versioned example routes should") {
it("return v1.0 calls") {
Get("/api/v1_0/user") ~> VersionedRoute.route ~> check {
responseAs[String] should equal("user")
}
Get("/api/v1_0/topicsearch/blah") ~> VersionedRoute.route ~> check {
responseAs[String] should equal("blah")
}
}
it("return v1.1 user") {
Get("/api/v1_1/user") ~> VersionedRoute.route ~> check {
responseAs[String] should equal("user")
}
Get("/api/v1_1/topicsearch/blah") ~> VersionedRoute.route ~> check {
responseAs[String] should equal("blah")
}
Get("/api/v1_1/geolocate") ~> VersionedRoute.route ~> check {
responseAs[String] should equal("geolocate")
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment