Reputation: 329
My spray rest service invokes other actors(passing RequestContext in constructor) to perform business logic(similar to this approach). I have a use case where I need to read json text from a file and return the content. I want the content type to be JSON. How do I set content type to json explictly with requestcontext.
In the code snippet below requestContext needs to return string(Json) with Json content type. requestContext.complete("{\"name\":\"John\"}")
package com.christophergagne.sprayapidemo
import akka.actor.{Actor, ActorRef}
import akka.event.Logging
import akka.io.IO
import spray.routing.RequestContext
import spray.httpx.SprayJsonSupport
import spray.client.pipelining._
import scala.util.{ Success, Failure }
object TimezoneService {
case class Process(long: Double, lat: Double, timestamp: String)
}
class TimezoneService(requestContext: RequestContext) extends Actor {
import TimezoneService._
implicit val system = context.system
import system.dispatcher
val log = Logging(system, getClass)
def receive = {
case Process(long,lat,timestamp) =>
process(long,lat,timestamp)
context.stop(self)
}
def process(long: Double, lat: Double, timestamp: String) = {
log.info("Requesting timezone long: {}, lat: {}, timestamp: {}", long, lat, timestamp)
import TimezoneJsonProtocol._
import SprayJsonSupport._
val pipeline = sendReceive ~> unmarshal[GoogleTimezoneApiResult[Timezone]]
val responseFuture = pipeline {
Get(s"https://maps.googleapis.com/maps/api/timezone/json?location=$long,$lat×tamp=$timestamp&sensor=false")
}
responseFuture onComplete {
case Success(GoogleTimezoneApiResult(_, _, timeZoneName)) =>
log.info("The timezone is: {} m", timeZoneName)
***requestContext.complete("{\"name\":\"John\"}")***
case Failure(error) =>
requestContext.complete(error)
}
}
}
thank you for help.
Upvotes: 0
Views: 557
Reputation: 2326
You need to return a full HttpResponse
object instead of a simple string. I recommend you do this:
import spray.routing.RequestContext
import spray.http._
requestContext.complete(HttpResponse(StatusCodes.OK, HttpEntity(ContentType(MediaTypes.`application/json`), "{\"name\":\"John\"}")))
You could also return only the HttpEntity
since it has a defined ToResponseMarshaller
which can be found here. Use it like so:
import spray.routing.RequestContext
import spray.http._
requestContext.complete(HttpEntity(ContentType(MediaTypes.`application/json`), "{\"name\":\"John\"}"))
I don't recommend you use string interpolation to return your JSON since this makes it hard to change the response structure. I recommend you use the spray-json
library which already has a ToReponseMarshaller
defined which can be found here. The functionality is documented here. Your code would look something like this:
import spray.routing.RequestContext
import spray.httpx.marshalling._
import spray.json._
import spray.httpx.SprayJsonSupport._
requestContext.complete(JsObject("name" -> JsString("John")))
Upvotes: 1
Reputation: 2804
If you need to make your reply an application/json
, you should use something like:
respondWithMediaType(MediaTypes.`application/json`) {
complete { ...
}
}
Upvotes: 1