Skip to content

Instantly share code, notes, and snippets.

@iximeow
Created September 9, 2015 21:40
Show Gist options
  • Save iximeow/4b824cd9bffd1887bfc5 to your computer and use it in GitHub Desktop.
Save iximeow/4b824cd9bffd1887bfc5 to your computer and use it in GitHub Desktop.
restricting Spray api response types
// Wanted to ensure complete() was only called with a certain response type, to give guarantees about api response structure
// (no accidental "returned a string when it should be json!" or "didn't actually give a body when I should have")
trait CustomRouteDirectives extends spray.routing.directives.RouteDirectives {
import spray.httpx.marshalling.ToResponseMarshallable
import spray.httpx.marshalling.ToResponseMarshallable.{isMarshallable => _}
import spray.httpx.marshalling.ToResponseMarshaller
import spray.httpx.marshalling.ToResponseMarshaller.{
eitherMarshaller,
futureMarshaller,
liftMarshaller,
liftMarshallerConversion,
optionMarshaller,
tryMarshaller,
fromStatusCode => _
}
/* And filling out implicit defs to convert to the restricted ToResponseMarshaller[T] types... */
//implicit def fromEitherM: ToRespon
// well. this is exactly the point where I threw my hands up and said not worth it (for now)
class RestrictedToResponseMarshaller[T](marshaller: ToResponseMarshaller[T])
object RestrictedToResponseMarshaller {
implicit def fromToResponseMarshaller[T](marshaller: ToResponseMarshaller[T])(implicit restrictor: ToResponseMarshaller[T] => RestrictedToResponseMarshaller[T]) =
restrictor(marshaller)
}
implicit def fromStatusCode = ()
implicit def toMarshaller[T](value: T)(implicit marshaller: RestrictedToResponseMarshaller[T]) =
ToResponseMarshallable.isMarshallable(value)(marshaller)
override def complete: (=> ToResponseMarshallable) => StandardRoute =
response => new StandardRoute {
def apply(ctx: RequestContext): Unit = ctx.complete(
response
)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment