[Play 2.6 Scala] action builder based action composition example?

1,189 views
Skip to first unread message

Chris Nappin

unread,
Jul 6, 2017, 4:18:03 AM7/6/17
to Play Framework
Hi,

  I must admit I'm a bit confused by "Action" being deprecated and replaced by injected ActionBuilders, as all of the examples in the Play 2.6 documentation on action composition etc still use an Action case class, as does the CSRF implementation.

  Is there an example of the "Play 2.6 idiomatic way" of doing action composition please?

Cheers,

  Chris

Chris Nappin

unread,
Jul 7, 2017, 7:19:08 AM7/7/17
to Play Framework
So far I have created the following code - it doesn't use Action and it works when composing with other injected action builders (e.g. MessagesActionBuilder) but not with legacy Actions:

class MyActionBuilder @Inject()(parser: BodyParsers.Default)(implicit ec: ExecutionContext)
      extends ActionBuilderImpl(parser) {

  def apply[A](action: Action[A]) = async(action.parser) { request =>
    action(request)
  }

  override def invokeBlock[A](request: Request[A], block: (Request[A]) => Future[Result]) = {
    // my own logic here, delegating to block(request)
  }
}


Will Sargent

unread,
Jul 7, 2017, 11:33:50 PM7/7/17
to Play Framework
Action in a controller is an instance of an ActionBuilder, and if you look into the Controller logic you can see you can actually swap it out.  Custom action builders are covered here:

Chris Nappin

unread,
Jul 10, 2017, 4:59:51 AM7/10/17
to Play Framework
Thanks Will, in my use case I'm after a custom action builder that others can mix in with their controllers, which could involve other custom actions and any base controller.

Extending ActionBuilderImpl and implementing "invokeBlock" results in an action builder that can be used directly on its own, but not composed with other Actions.

For example:

  def method1 = myAction {
     
Ok("hello")
 
}

But not:

def method2 = myAction {
 
Action {
   
Ok("hello")
 
}
}

Adding an explicit apply(Action[A]) method to my action builder allows composition like above, but is that correct? Is there a way to use "ActionFunction.compose(..)" that I'm missing perhaps?

The latest docs you linked to still include using a case class to wrap the deprecated Action - I assume this is really a deprecated approach (and of no use when you need dependency injection, which I do in this scenario).



Jevin G

unread,
Jul 30, 2017, 11:41:09 PM7/30/17
to Play Framework
A little late, but you can use andThen to compose composite actions.
Reply all
Reply to author
Forward
0 new messages