examples using rapture-json-spray

165 views
Skip to first unread message

Benjamin Neil

unread,
Jan 25, 2015, 4:15:38 PM1/25/15
to raptur...@googlegroups.com
Hello,
I've been trying to wrap my head around how to integrate the rapture-json lib into my spray application. Specifically how to extract nested objects using rapture in the route dsl.

For example:

case class Authentication(credentials: Credentials)
case class Credentials(username: String, password:String)

then in the spray route I have code similar to:

import rapture.json.jsonBackends.spray._
trait ClientRoutes extends HttpService {
  val clientRoutes = {
    path("account" / "auth") { 
      post {
        entity(sprayJsObjectExtractor[Authentication]) { c =>
          respondWithMediaType(`application/json`) {
            println(c)
            complete("woot")
          }
        }
      }
    }
  }
}

however this results in:
value sprayJsObjectExtractor of type rapture.json.internal.JsonCastExtractor[spray.json.JsObject] does not take type parameters.

which makes sense since I am using it improperly. :)

Would you happen to have an example or a place where I could start looking for examples of how to utilize the rapture extractors properly within spray?

Thanks
Ben

Jon Pretty

unread,
Jan 26, 2015, 6:48:55 AM1/26/15
to raptur...@googlegroups.com
Hi Benjamin,

I don't have a lot of experience with Spray itself, so you might have to help me along with any Spray specifics...

First of all, just to make sure we're on the same page, I guess you've seen that Rapture JSON works with multiple backends, one of which is Spray JSON. That doesn't actually have a lot to do with any other part of Spray, so you could quite happily use Rapture JSON with a different backend (e.g. Jackson or Jawn) with Spray.

The examples from the Rapture JSON Github page are equally applicable to all backends.

However, one good reason for using Rapture JSON with the Spray backend is that you are already using Spray JSON, i.e. you already have JSON objects created directly by Spray. So, if you have some JSON values from Spray, e.g. an instance of `spray.json.JsObject`, you can convert that directly into a Rapture JSON value just by wrapping it in `Json(...)`, e.g.

  val mySprayJsObject: JsObject = ...
  val myRaptureJsonObject: Json = Json(mySprayObject)

You can then use all the Rapture JSON features on this new object.

Conversely, if you've got an existing Rapture JSON value, and you want to convert it to a native Spray JSON object, you can call `myRaptureJsonObject.as[JsValue]` or `myRaptureJsonObject.as[JsObject]` (depending on which type you want).

Both of these conversions are constant time operations, assuming you're using a matching backend (which you are, here).

Going back to your example, first of all, you should import `rapture.json._` as well as `jsonBackends.spray._`. It looks like you've tried to call the value `sprayJsValueExtractor` directly, which you should never need to do. It's an implicit, so it will get resolved when it's required.

I'm not sure how the `entity` directive works here, but if you give me a bit more detail on what you're trying to do, I'd be happy to explain it!

Good luck!
Jon

--
You received this message because you are subscribed to the Google Groups "Rapture users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rapture-user...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
Jon Pretty | @propensive

Benjamin Neil

unread,
Jan 26, 2015, 1:56:40 PM1/26/15
to raptur...@googlegroups.com
Hi Jon, I appreciate the quick feedback.
Ok, I had assumed that the rapture spray backend was going to have (un)marshallers that worked directly with spray entities so I wouldn't need to create implicits for spray and then manually convert the JsObject to rapture. 

For example, rather then having to write the implicits for spray-json:

object JsonImplicits extends DefaultJsonProtocol {
  implicit val credentialsFormat = jsonFormat2(Credentials)
  implicit val authFormat: RootJsonFormat[Auth] = jsonFormat(Authentication.apply, "credentials")
}

then in the route:
        entity(as[JsObject]) { c =>
             val creds = Json(c).as[Authentication].credentials
 
which works, I had imagined the process would work more like

entity(json.as[Authentication){ c =>

without having to use spray-json for the unmarshalling. 

Ben

Jon Pretty

unread,
Jan 28, 2015, 11:49:06 AM1/28/15
to raptur...@googlegroups.com

Hi Ben,

Great! Glad you made sense of it.

Maybe we could do better with the default set of stuff we bundle into rapture-json-spray. Everything in there at the moment is to make Rapture JSON support Spray JSON as a backend, though it might be possible to provide a few Spray implicits which provide better support for Rapture instead.

I'll investigate further, though (as I mentioned before) I don't really know Spray, so any pull requests which save me the trouble would be most welcome!

Thanks!
Jon

Reply all
Reply to author
Forward
0 new messages