[2.1.0 scala] Help combining body parser or actions

240 views
Skip to first unread message

Jun Yamog

unread,
Feb 9, 2013, 10:34:29 PM2/9/13
to play-framework
Hi,

I would like to ask help in my problem. I would like to add another
action in my controller, its mostly a wrapper to an existing one.
e.g.

def newRestCall = oldRestCall

def oldRestCall

Naturally I want to do something in between newRestCall and
oldRestCall. More specifically decrypting the posted message on
newRestCall, add something to Json before passing it to the
oldRestCall.

I am reading this to help me, however unable to further progress forward.

http://www.playframework.com/documentation/2.1.0/ScalaActionsComposition
http://www.playframework.com/documentation/2.1.0/ScalaBodyParsers

It seems action composition I can't change the body anymore? As I
would like to decrypt body in newRestCall and create a json request
before giving it to oldRestCall.

While on the body parsers, I don't know how to use the oldRestCall
after changing the body.

I guess I can refactor it so newRestCall and oldRestCall can share
some common code. However its really just a transform and call
oldRestCall what I am after. I really would appreciate if someone can
tell me which one to use and I guess just a basic example. Thanks.

Jun

Jun Yamog

unread,
Feb 10, 2013, 3:26:16 AM2/10/13
to play-framework
Not too happy with the solution I came up. As it starts with
application/json, but technically it starts not as a json request but
just plain text. So its really not yet a valid jsvalue. Can someone
help me make this better?

def decryptAction(action: Action[JsValue]): Action[JsValue] = {
Action(action.parser) { request =>
val decryptedRequest = request.map{
case body: JsValue => {
val decrypted = decrypt(body.toString)
Json.parse(s"""{"foo": "$decrypted", "bar": false}""")
}
}
action(decryptedRequest)
}
}
def newRestCall = decryptAction {
oldRestCall

Nilanjan Raychaudhuri

unread,
Feb 11, 2013, 10:15:42 AM2/11/13
to play-fr...@googlegroups.com
I would prefer a new type of BodyParsers. This is something I don't is documented very well - you can compose body parsers to create a new body parsers:

val newParser = BodyParsers.parse.using { request =>

//decrypt
}

Now use the new bodyParser for the action.

Nilanjan, Developer & Consultant
Typesafe Inc.
Twitter: @nraychaudhuri

Jun Yamog

unread,
Feb 14, 2013, 4:16:32 AM2/14/13
to play-framework
Hi,

The combined action does work, however like you suggested its better
to make a body parser. I am a bit stumped on how to make it work.

here is what I have:

val decryptParser = parse.using[JsValue]{ reqHeader =>
parse.json.map{ jsValue =>
decrypt(jsValue)
}
}

def newAction = Action(decryptParser) {
sharedCode
}

Pretty sure its wrong, as I only get the original json value.
parse.json.map does not work/executed. I don't know where to proceed
on how to create a BodyParser[JsValue]. My decrypt is simply produces
a JsObject. Thanks in advance.

Jun
> --
> You received this message because you are subscribed to the Google Groups
> "play-framework" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to play-framewor...@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.
>
>

Nilanjan Raychaudhuri

unread,
Feb 14, 2013, 4:27:19 AM2/14/13
to play-fr...@googlegroups.com
The using will allow you to choose the right BodyParser. But if you want to go from BodyParser[A] to BodyParser[B] use map

val decryptParser = someParser.map { encryptedBody =>
  //decrypt here


}

Nilanjan, Developer & Consultant
Typesafe Inc.
Twitter: @nraychaudhuri

Jun Yamog

unread,
Feb 15, 2013, 3:48:12 AM2/15/13
to play-framework
Thank you Nilanjan.

Here is what I ended up, hopefully would be useful for others:

val decryptParser = parse.json.map (decryptValue)

def oldRestCall = Action(parse.json) {
sharedCode
}

def newRestCall = Action(decryptParser) {
sharedCode
Reply all
Reply to author
Forward
0 new messages