Last active
August 29, 2015 13:57
-
-
Save davidmweber/9808705 to your computer and use it in GitHub Desktop.
Using Spray to return different marshalling formats based on an Accept type in the request header
This file contains hidden or 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
import org.scalatest.{FunSpec, Matchers} | |
import spray.http.HttpHeaders.Accept | |
import spray.http.HttpEntity | |
import spray.http.MediaTypes._ | |
import spray.httpx.marshalling._ | |
import spray.routing.Directives._ | |
import spray.routing.HttpService.sealRoute | |
import spray.testkit.ScalatestRouteTest | |
import spray.json._ | |
import spray.httpx.SprayJsonSupport._ | |
// All the fuss is about this... | |
case class Order(name: String, no: Int) | |
// Custom marshalling for our text/plain | |
object OurMarshaller extends DefaultJsonProtocol { | |
// You must explicitly type jsonOrder as a Marshaller[T] | |
val jsonOrder: Marshaller[Order] = jsonFormat2(Order) | |
val textOrder = Marshaller.of[Order](`text/plain`) { | |
(value, content, ctx) => ctx.marshalTo(HttpEntity(content, value.toString)) | |
} | |
implicit val orderMarshal: ToResponseMarshaller[Order] = | |
ToResponseMarshaller.oneOf(`application/json`, `text/plain`)(jsonOrder, textOrder) | |
} | |
class TestMarshalByAccept extends FunSpec with ScalatestRouteTest with Matchers { | |
import OurMarshaller._ | |
// Marshals response according to the Accept header media type | |
val fetchOrder = path("order" / IntNumber) { | |
id => get { | |
complete(Order("Bender", id)) | |
} | |
} | |
describe("Our route should") { | |
val str = """{ | |
| "name": "Bender", | |
| "no": 1234 | |
|}""".stripMargin | |
it("return a json if requested") { | |
Get("/order/1234").withHeaders(Accept(`application/json`)) ~> fetchOrder ~> check { | |
contentType.mediaType.toString() should equal(Accept(`application/json`).value) | |
responseAs[String] should equal(str) | |
} | |
} | |
it("return text if requested") { | |
Get("/order/1235").withHeaders(Accept(`text/plain`)) ~> fetchOrder ~> check { | |
contentType.mediaType.toString should equal(Accept(`text/plain`).value) | |
responseAs[String] should equal(Order("Bender", 1235).toString) | |
} | |
} | |
it("fail with unknown media types") { | |
Get("/order/1234").withHeaders(Accept(`text/html`)) ~> sealRoute(fetchOrder) ~> check { | |
status.intValue should equal(406) | |
} | |
} | |
it("give us json with no Accept header") { | |
Get("/order/1234") ~> sealRoute(fetchOrder) ~> check { | |
contentType.mediaType.toString should equal(Accept(`application/json`).value) | |
println(responseAs[String]) | |
responseAs[String] should equal(str) | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment