2
votes

I am wondering whether Play framework controller can do automatically convert between JSON and Object (case class) without some boilerplate.

As Spring MVC and Twitter's Finatra can do that. Following is the code for Finatra framework.

@Singleton
class TweetsController @Inject()(
  tweetsService: TweetsService)
  extends Controller {

  post("/tweet") { requestTweet: TweetPostRequest =>
    // requestTweet is a case class mapping json request
    tweetsService.save(requestTweet)
    ...
  }

  get("/tweet/:id") { request: TweetGetRequest =>
    // case class mapping json response
    tweetsService.getResponseTweet(request.id)
    ...
  }
}

However, for Play framework, we need do JSON conversation manually. Can Play support a way without using implicit to do that?

Any reasons why Play can't support that or will it support in the future release?

1

1 Answers

2
votes

We use the following utility class for this purpose

  /**
   * Framework method for handling a request that takes a Json body as a parameter. If the JSON body can be
   * parsed as a valid instance of  `A` , the resulting object is passed into the body which is expected
   * to produce a Result.
   *       
   *
   * Note that it is not necessary to create the Action object in the body of the supplied handler; this is
   * done for you.
   *
   * @tparam A A case class that the input JSON should be parsed into.
   * @param body The body of the handler for this request. This must be a function that will take an instance of `A`
   * and use it generate a `Result`.
   *
   */
  def handleJsonRequest[A : Reads](body: A => Result) = Action(parse.json) { request =>
    request.body.validate[A].map {body}.recoverTotal {
        errors: JsError =>
          throw new ...(errors)
      }
  }

You can use this in your handler as

def handleGet() = handleJsonRequest[Body] {body =>
  ...
}