Permalink
Browse files

! routing: upgrade to new ToResponseMarshaller, closes #293

Removes `RequestContext::marshallingContext`. Also: the `produce` directive looses its `status` and `headers` parameters.
Use the new `ToResponseMarshaller.fromMarshaller` creator instead.
  • Loading branch information...
sirthias committed Oct 1, 2013
1 parent 1035706 commit b145ced33a5a4cb3d103ae792e1afbce91e00c2d
@@ -21,8 +21,7 @@ import scala.concurrent.{ ExecutionContext, Future }
import scala.util.{ Failure, Success }
import akka.actor.{ Status, ActorRef }
import akka.spray.UnregisteredActorRef
-import spray.httpx.marshalling.{ MarshallingContext, Marshaller }
-import spray.util._
+import spray.httpx.marshalling._
import spray.http._
import StatusCodes._
import HttpHeaders._
@@ -226,8 +225,21 @@ case class RequestContext(request: HttpRequest, responder: ActorRef, unmatchedPa
* Completes the request with status "200 Ok" and the response entity created by marshalling the given object using
* the in-scope marshaller for the type.
*/
- def complete[T: Marshaller](obj: T): Unit =
- complete(OK, obj)
+ def complete[T](obj: T)(implicit marshaller: ToResponseMarshaller[T]): Unit = {
+ val ctx = new ToResponseMarshallingContext {
+ def tryAccept(contentTypes: Seq[ContentType]) = request.acceptableContentType(contentTypes)
+ def rejectMarshalling(onlyTo: Seq[ContentType]): Unit = reject(UnacceptedResponseContentTypeRejection(onlyTo))
+ def marshalTo(response: HttpResponse): Unit = complete(response)
+ def handleError(error: Throwable): Unit = failWith(error)
+ def startChunkedMessage(response: HttpResponse, sentAck: Option[Any])(implicit sender: ActorRef) = {
+ val chunkStart = ChunkedResponseStart(response)
+ val wrapper = if (sentAck.isEmpty) chunkStart else Confirmed(chunkStart, sentAck.get)
+ responder.tell(wrapper, sender)
+ responder
+ }
+ }
+ marshaller(obj, ctx)
+ }
/**
* Completes the request with the given status and the response entity created by marshalling the given object using
@@ -240,8 +252,22 @@ case class RequestContext(request: HttpRequest, responder: ActorRef, unmatchedPa
* Completes the request with the given status, headers and the response entity created by marshalling the
* given object using the in-scope marshaller for the type.
*/
- def complete[T](status: StatusCode, headers: List[HttpHeader], obj: T)(implicit marshaller: Marshaller[T]): Unit =
- marshaller(obj, marshallingContext(status, headers))
+ def complete[T](status: StatusCode, headers: List[HttpHeader], obj: T)(implicit marshaller: Marshaller[T]): Unit = {
+ val ctx = new MarshallingContext {
+ def tryAccept(contentTypes: Seq[ContentType]) = request.acceptableContentType(contentTypes)
+ def rejectMarshalling(onlyTo: Seq[ContentType]): Unit = reject(UnacceptedResponseContentTypeRejection(onlyTo))
+ def marshalTo(entity: HttpEntity, headers: HttpHeader*): Unit = complete(response(entity, headers))
+ def handleError(error: Throwable): Unit = failWith(error)
+ def startChunkedMessage(entity: HttpEntity, sentAck: Option[Any], headers: Seq[HttpHeader])(implicit sender: ActorRef) = {
+ val chunkStart = ChunkedResponseStart(response(entity, headers))
+ val wrapper = if (sentAck.isEmpty) chunkStart else Confirmed(chunkStart, sentAck.get)
+ responder.tell(wrapper, sender)
+ responder
+ }
+ def response(entity: HttpEntity, h: Seq[HttpHeader]) = HttpResponse(status, entity, headers ++ h)
+ }
+ marshaller(obj, ctx)
+ }
/**
* Completes the request with the given [[spray.http.HttpResponse]].
@@ -270,24 +296,6 @@ case class RequestContext(request: HttpRequest, responder: ActorRef, unmatchedPa
case x Status.Failure(x)
}
}
-
- /**
- * Creates a MarshallingContext using the given status code and response headers.
- */
- def marshallingContext(status: StatusCode, headers: List[HttpHeader]): MarshallingContext =
- new MarshallingContext {
- def tryAccept(contentTypes: Seq[ContentType]) = request.acceptableContentType(contentTypes)
- def rejectMarshalling(onlyTo: Seq[ContentType]): Unit = reject(UnacceptedResponseContentTypeRejection(onlyTo))
- def marshalTo(entity: HttpEntity, headers: HttpHeader*): Unit = complete(response(entity, headers))
- def handleError(error: Throwable): Unit = failWith(error)
- def startChunkedMessage(entity: HttpEntity, sentAck: Option[Any], headers: Seq[HttpHeader])(implicit sender: ActorRef) = {
- val chunkStart = ChunkedResponseStart(response(entity, headers))
- val wrapper = if (sentAck.isEmpty) chunkStart else Confirmed(chunkStart, sentAck.get)
- responder.tell(wrapper, sender)
- responder
- }
- def response(entity: HttpEntity, h: Seq[HttpHeader]) = HttpResponse(status, entity, headers ++ h)
- }
}
case class Rejected(rejections: List[Rejection]) {
@@ -20,7 +20,6 @@ package directives
import akka.actor.ActorRefFactory
import spray.http.{ HttpData, HttpEntity, HttpResponse }
import spray.httpx.marshalling.BasicMarshallers
-import akka.util.ByteString
trait ChunkingDirectives {
import BasicDirectives._
@@ -21,7 +21,7 @@ import shapeless._
import scala.concurrent.{ ExecutionContext, Future }
import scala.util.control.NonFatal
import scala.util.{ Failure, Success, Try }
-import spray.httpx.marshalling.Marshaller
+import spray.httpx.marshalling.ToResponseMarshaller
trait FutureDirectives {
@@ -86,7 +86,7 @@ object OnSuccessFutureMagnet {
trait OnFailureFutureMagnet extends Directive1[Throwable]
object OnFailureFutureMagnet {
- implicit def apply[T](future: Future[T])(implicit m: Marshaller[T], ec: ExecutionContext) =
+ implicit def apply[T](future: Future[T])(implicit m: ToResponseMarshaller[T], ec: ExecutionContext) =
new OnFailureFutureMagnet {
def happly(f: (Throwable :: HNil) Route) = ctx future.onComplete {
case Success(t) ctx.complete(t)
@@ -20,7 +20,6 @@ package directives
import shapeless._
import spray.httpx.marshalling._
import spray.httpx.unmarshalling._
-import spray.http._
trait MarshallingDirectives {
import BasicDirectives._
@@ -49,25 +48,20 @@ trait MarshallingDirectives {
* Uses the marshaller for the given type to produce a completion function that is passed to its inner route.
* You can use it do decouple marshaller resolution from request completion.
*/
- def produce[T](marshaller: Marshaller[T], status: StatusCode = StatusCodes.OK,
- headers: List[HttpHeader] = Nil): Directive[(T Unit) :: HNil] =
- extract { ctx
- (value: T)
- marshaller(value, ctx.marshallingContext(status, headers))
- } & cancelAllRejections(ofType[UnacceptedResponseContentTypeRejection])
+ def produce[T](marshaller: ToResponseMarshaller[T]): Directive[(T Unit) :: HNil] =
+ extract { ctx (value: T) ctx.complete(value)(marshaller) } & cancelAllRejections(ofType[UnacceptedResponseContentTypeRejection])
/**
* Returns the in-scope Marshaller for the given type.
*/
- def instanceOf[T](implicit m: Marshaller[T]) = m
+ def instanceOf[T](implicit m: ToResponseMarshaller[T]) = m
/**
* Completes the request using the given function. The input to the function is produced with the in-scope
* entity unmarshaller and the result value of the function is marshalled with the in-scope marshaller.
*/
- def handleWith[A, B](f: A B)(implicit um: FromRequestUnmarshaller[A], m: Marshaller[B]): Route =
+ def handleWith[A, B](f: A B)(implicit um: FromRequestUnmarshaller[A], m: ToResponseMarshaller[B]): Route =
entity(um) { a RouteDirectives.complete(f(a)) }
-
}
object MarshallingDirectives extends MarshallingDirectives
@@ -18,7 +18,7 @@ package spray.routing
package directives
import scala.concurrent.{ ExecutionContext, Future }
-import spray.httpx.marshalling.Marshaller
+import spray.httpx.marshalling.{ Marshaller, ToResponseMarshaller }
import spray.http._
import StatusCodes._
@@ -66,14 +66,14 @@ object RouteDirectives extends RouteDirectives
sealed abstract class CompletionMagnet extends Route
object CompletionMagnet {
- implicit def fromObject[T: Marshaller](obj: T): CompletionMagnet =
- new CompletionRoute(OK, Nil, obj)
+ implicit def fromObject[T: ToResponseMarshaller](obj: T): CompletionMagnet =
+ new CompletionRoute(obj)
implicit def fromStatusObject[T: Marshaller](tuple: (StatusCode, T)): CompletionMagnet =
- new CompletionRoute(tuple._1, Nil, tuple._2)
+ fromStatusHeadersObject((tuple._1, Nil, tuple._2))
implicit def fromStatusHeadersObject[T: Marshaller](tuple: (StatusCode, List[HttpHeader], T)): CompletionMagnet =
- new CompletionRoute(tuple._1, tuple._2, tuple._3)
+ new CompletionRoute(tuple._3)(ToResponseMarshaller.fromMarshaller(tuple._1, tuple._2))
implicit def fromHttpResponse(response: HttpResponse): CompletionMagnet =
new CompletionMagnet {
@@ -90,7 +90,7 @@ object CompletionMagnet {
implicit def fromStatusCodeFuture(future: Future[StatusCode])(implicit ec: ExecutionContext): CompletionMagnet =
future.map(status HttpResponse(status, entity = status.defaultMessage))
- private class CompletionRoute[T: Marshaller](status: StatusCode, headers: List[HttpHeader], obj: T) extends CompletionMagnet {
- def apply(ctx: RequestContext): Unit = ctx.complete(status, headers, obj)
+ private class CompletionRoute[T: ToResponseMarshaller](obj: T) extends CompletionMagnet {
+ def apply(ctx: RequestContext): Unit = ctx.complete(obj)
}
}

0 comments on commit b145ced

Please sign in to comment.