Reputation: 9621
In a Play Framework project, I have controllers for handling REST request, an example would be:
object AddressBean extends Controller with RestTrait{
def list = Action {
val list = Addresses.findAll()
Ok(Json.toJson(list.map(s => Json.toJson(s)(AddressJson.addressWrites))))
}
def create = Action {
Ok("")
}
}
(please note that I just put OK("") to compile, I have to implement them, like I implemented list method).
I want to define a trait for all these REST classes to implement the same methods and I started like:
/**
* Define an interface for all of our REST classes.
*/
trait RestTrait extends Controller{
/**
* List entities.
*/
def list
/**
* Create entity. Get entity from request.body
*/
def create
//and so on
}
The issue is that I receive a warning saying Unit does not take parameters
so I understand that my methods from trait should have an Action return type so I end up defining them like:
/**
* Define an interface for all of our REST classes.
*/
trait RestTrait extends Controller{
/**
* List entities.
*/
def list = Action{
Ok("")
}
/**
* Create entity. Get entity from request.body
*/
def create = Action{
Ok("")
}
//and so on
}
Isn't there any way to avoid defining methods in trait like this? Because then I have to use override
in my classes. I mainly want to implement
not override
those methods...
Upvotes: 2
Views: 491
Reputation: 9067
Abstract methods without a return type will return Unit, so all you have to do is to add return type of Action[AnyContent] to your methods.
trait RestTrait extends Controller{
/**
* List entities.
*/
def list:play.api.mvc.Action[play.api.mvc.AnyContent]
/**
* Create entity. Get entity from request.body
*/
def create:play.api.mvc.Action[play.api.mvc.AnyContent]
//and so on
}
Action is in fact a singleton object that accepts a function which returns a Result.
object Action extends java.lang.Object with scala.ScalaObject {
...
def apply(block : scala.Function1[play.api.mvc.Request[play.api.mvc.AnyContent], play.api.mvc.Result]) : play.api.mvc.Action[play.api.mvc.AnyContent]
def apply(block : => play.api.mvc.Result) : play.api.mvc.Action[play.api.mvc.AnyContent]
}
Upvotes: 5