Created
March 30, 2014 08:48
-
-
Save davidmweber/9869773 to your computer and use it in GitHub Desktop.
Route based marshalling example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package za.co.monadic.kumquat | |
import spray.testkit.ScalatestRouteTest | |
import org.scalatest.{FunSpec, Matchers} | |
import spray.json.DefaultJsonProtocol | |
import spray.routing.Directives._ | |
import spray.httpx.marshalling.Marshaller | |
import spray.http.MediaTypes._ | |
import spray.http.HttpEntity | |
// Data types that we trade in | |
case class Customer(name: String, no: Int) | |
case class Part( number: Int, name: String, length: Double) | |
// Marshallers for application/json (Spray's json) | |
object JsonMarshallers extends DefaultJsonProtocol { | |
implicit val customerM = jsonFormat2(Customer) | |
implicit val partM = jsonFormat3(Part) | |
} | |
// Custom marshalling for our text/plain | |
object TextMarshal { | |
implicit val customerM = Marshaller.of[Customer](`text/plain`) { | |
(value, content, ctx) => ctx.marshalTo(HttpEntity(content, value.toString)) | |
} | |
implicit val partM = Marshaller.of[Part](`text/plain`) { | |
(value, content, ctx) => ctx.marshalTo(HttpEntity(content, value.toString)) | |
} | |
} | |
// Map implicit | |
trait JsonApi { | |
import spray.httpx.SprayJsonSupport._ | |
implicit val cm = sprayJsonMarshallerConverter(JsonMarshallers.customerM) | |
implicit val pm = sprayJsonMarshallerConverter(JsonMarshallers.partM) | |
} | |
trait TextApi { | |
implicit val cm = TextMarshal.customerM | |
implicit val pm = TextMarshal.partM | |
} | |
// Build marshal format independent routing | |
sealed trait Routes { | |
implicit val cm: Marshaller[Customer] | |
implicit val pm: Marshaller[Part] | |
val customer = path("customer" / IntNumber ){ id => complete(Customer("Frankie",id)) } | |
val part = path("part" / IntNumber ){ partNo => complete(Part(partNo,"Power flubber", 1.33)) } | |
val route = pathPrefix("v1_0" ) { | |
get { | |
part ~ customer | |
} | |
} | |
} | |
// Json mashalled route | |
object JsonRoutes extends Routes with JsonApi { | |
val topRoute = pathPrefix("api" / "json" ) { route } | |
} | |
// Text marshalled route | |
object TextRoutes extends Routes with TextApi { | |
val topRoute = pathPrefix("api" / "txt" ) { route } | |
} | |
/** | |
* Test case for the configuration above | |
*/ | |
class RouteTest extends FunSpec with ScalatestRouteTest with Matchers{ | |
import spray.json._ | |
import JsonMarshallers._ | |
describe("Our routes should") { | |
it("gets our customers as text") { | |
Get("/api/txt/v1_0/customer/233") ~> TextRoutes.topRoute ~> check { | |
responseAs[String] should equal(Customer("Frankie", 233).toString) | |
} | |
} | |
it("gets part details as text") { | |
Get("/api/txt/v1_0/part/233") ~> TextRoutes.topRoute ~> check { | |
responseAs[String] should equal(Part(233, "Power flubber", 1.33).toString) | |
} | |
} | |
it("gets our customers as JSON") { | |
Get("/api/json/v1_0/customer/233") ~> JsonRoutes.topRoute ~> check { | |
responseAs[String] should equal(Customer("Frankie", 233).toJson.prettyPrint) | |
} | |
} | |
it("gets our part details as JSON") { | |
Get("/api/json/v1_0/part/23") ~> JsonRoutes.topRoute ~> check { | |
responseAs[String] should equal(Part(23, "Power flubber", 1.33).toJson.prettyPrint) | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment