How to write a Play Framework POST request web service

This is an excerpt from the Scala Cookbook (partially modified for the internet). This is Recipe 15.15, “How to write a Scala Play Framework POST request web service.”

Problem

You want to create a Scala web service using the Play Framework that lets users send JSON data to the service using the POST request method.

Solution

Follow the steps from the previous recipe to create a new Play project, controller, and model.

Whereas the previous recipe used the writes method of the Format object in the model, this recipe uses the reads method. When JSON data is received in a POST request, the reads method is used to convert from the JSON string that’s received to a Stock object.

Here’s the code for the reads method:

def reads(json: JsValue): JsResult[Stock] = {
    val symbol = (json \ "symbol").as[String]
    val price = (json \ "price").as[Double]
    JsSuccess(Stock(symbol, price))
}

This method creates a Stock object from the JSON value it’s given. (The complete code for the model object is shown in the previous recipe.)

With this method added to the model, create a saveStock method in the Application controller:

import play.api._
import play.api.mvc._

object Application extends Controller {
    import play.api.libs.json.Json
    def saveStock = Action { request =>
        val json = request.body.asJson.get
        val stock = json.as[Stock]
        println(stock)
        Ok
    }
}

The saveStock method gets the JSON data sent to it from the request object, and then converts it with the json.as method. The println statement in the method is used for debugging purposes, and prints to the Play command line (the Play console).

Finally, add a route that binds a POST request to the desired URI and the saveStock method in the Application controller by adding this line to the conf/routes file:

POST   /saveStock     controllers.Application.saveStock

If you haven’t already done so, start the Play console from within the root directory of your project, and issue the run command:

$ play
[WebServicesDemo]

$ run 8080

With the Play server running, use the following Unix curl command to POST a sample JSON string to your saveStock web service:

curl \
    --header "Content-type: application/json" \
    --request POST \
    --data '{"symbol":"GOOG", "price":900.00}' \
    http://localhost:8080/saveStock

If everything works properly, you should see this output in your Play console window:

STOCK: Stock(GOOG,900.0)

Discussion

A few notes about the code:

  • The request object is a play.api.mvc.AnyContent object
  • The request.body is also a play.api.mvc.AnyContent object
  • request.body.asJson returns an instance of Option[play.api.libs.json.JsValue]
  • request.body.asJson.get returns a JsValue

In a real-world web service, once you’ve converted the JSON string to an object, you can do anything else you need to do with it, such as saving it to a database.

See Also