Enterprise Java

Play! Framework JSON & Scala Example

In this post, we feature a comprehensive Example on Play! Framework JSON & Scala. In my last two posts, we have discussed about Play Framework + Scala + SBT based project basics. Please refer Play! Framework Hello World Example and Play! Framework Path, Query and Route Default Params Example to understand Play + SBT Project structure, Project configurations, SBT configurations etc. This is my third post in Play! Framework Tutorial Series.

In my previous post, we have discussed about Play Framework basics with HelloWorld example. I hope you have experimented that example and waiting for next step in this series. If not done, better to go through my previous post first at Play! Framework Hello World Example to understand Play + Scala + SBT project structure and Play Framework basics.

In this post, we are going to discuss about one of the important module of Play! Framework: Play JSON Module with some simple and useful examples.

1. Introduction

Play! Framework is a High-productivity, Moulder and REST based Modern MVC web framework. By design, it supports REST API development using JSON over HTTP protocol. JSON is a Data Transfer or Data Exchange type that is Content Type.

JSON stands for JavaScript Object Notation. If you are new to JSON data format, please go through http://json.org website to learn some basics.

To support conversion between Scala Object and JSON, Play Framework has a separate module: Play JSON Module. It is one of the important and most frequently used module of Play! Framework.

If you want to go through the Play! JSON API source code, please go refer this GitHub url: https://github.com/playframework/play-json

Play JSON library has two kinds of API: one API for Java and another for Scala. In this post, we are going to concentrate on only Play JSON Scala API.

2. Technologies used

In this post, we are going to use the following technologies:

  • Scala 2.12.6
  • Play Framework 2.6.17
  • Play JSON 2.6.9
  • SBT 1.1.5
  • IntelliJ IDEA

Before exploring the next steps, please try to install Java 1.8 or later version and the above mentioned software. Let us start developing our first Play Scala Web Application in the next section.

3. Play JSON API Basics

Play! Framework supports JSON API as a separate Module and its name is play-json. The complete Play JSON API was defined in play.api.libs.json package in this module. Initial versions of Play Framework has this JSON API within main core module so it should be available only for Play Framework. Later they have moved this API into a separate module so we can used it for both Play Based projects and Non-Play Based Projects.

JSON is a light-weight plain text based Data Exchange format. It is Language, Platform (OS- Operating System) and Protocol Independent Data format.

The main goal of Play JSON API is to provide an API to support the following features:

  • Convert Scala Object to JSON Object
  • Convert JSON Object to Scala Object
  • Other JSON Utilities

If we want to use this Play JSON module in our project, we should add the following library dependency in our build.sbt file as shown below:

1
libraryDependencies += "com.typesafe.play" %% "play-json" % "2.6.9"

Like Java or Scala has Data types to represent values, Play JSON API also have the following Data Types to represent each and every JSON Data type.

  • JsString: It represents a Json string value.
  • JsNumber: It represents a Json number value.
  • JsBoolean: It represents a Json boolean value.
  • JsObject: It represents a Json object value.
  • JsArray: It represents a Json array value.
  • JsNull: It represents a Json null value.

All these Data types have a super component: JsValue and they all are organised as shown in the below diagram:

Play JSON Data Types

We will discuss about Play JSON API’s Reads, Writes and Format in the coming sections. Apart from these API, Play JSON API has few other utilities to support extra JSON functionalities like Json, JsPath etc.

3.1 Json Utilities

Like other Play JSON API, Json is also defined in play.api.libs.json package. It provides some utilities, which are mainly useful to convert to and from JsValue structures. It contains helper functions to handle JsValues.

Json.toJson(): To convert from Scala object to JsValue, we should use Json.toJson() utility as shown below:

1
2
import play.api.libs.json._
Json.toJson(HelloWorld("Json"))

Here HelloWorld is a Scala Case class, which takes a String as a parameter. When we pass this object to Json.toJson() utility, it will convert that Scala Object into JsValue as shown below:

Json.stringify(): To represent a JsValue as a String , we should use Json.stringify() utility as shown below:

1
2
import play.api.libs.json._
Json.stringify(Json.toJson(HelloWorld("Json")))

Here we first convert our HelloWorld case class into a JsValue using Json.toJson() function. Then we convert this JsValue into a String using Json.stringify() function.

parse(): It is quite the opposite to Json.stringify() function. To represent a String as a JsValue, we should use Json.parse() utility as shown below:

1
2
3
4
5
6
7
import play.api.libs.json._
val json: JsValue = Json.parse("""
  {
    "module" : "json",
  }
  """)

Here Scala String represents our HelloWorld case class in String format. Then we are converting that Scala String object into a JsValue using Json.parse() function.

3.2 JsPath Utilities

Like other Play JSON API, JsPath is also defined in play.api.libs.json package. JsPath represents a path into a JsValue structure. Like we use XPath to traverse XML Document, we can use JsPath to traverse JSON Object. We will extensively use it in writing Play Reads, Writes and Format implicit converters.

For instance, we have the following JSON String to represent our HelloWorld case class in String format.

1
2
3
4
5
6
7
import play.api.libs.json._
val json: String = """
  {
    "module" : "json",
  }
  """

Then we can access “module” property or the path to the “module” property is as shown below:

1
JsPath \ "module"

Suppose, we have submoulde property under module property, then we can access “submodule” property as shown below:

1
JsPath \ "module" \ "submodule"

JsPath is basic building block to write manual Reads/Writes/Format converters. We will explore on “How to write manual converters and how to use these helper functions or utilities” in-depth in the coming examples sections.

Play JSON API has the following three different Converters to convert JsValue to Scala Value (or Scala Object) and vice versa:

  • READS Converter
  • WRITES Converter
  • FORMAT Converter

Let us use the following case class to explore these three converters.

HelloWorld.scala

1
case class HelloWorld(module:String, submodule:String)

We will discuss these converters in-detail in the coming sections with some useful examples.

4. Play JSON Reads Converter

In Play JSON API, Reads Converters are used to convert a JsValue to a Value ( in specific words, its a Scala Value or Scala Object or Scala Type). Reads is also defined as a trait in play.api.libs.json package.

Here we can also use other words instead of “convert” word. It decodes or deserialises or converts a JsValue to a Scala Value as shown in the below diagram.

Play JSON Reads Converter

So Reads converter is also know as “Deserialiser” as it deserialises a JSON type (JsValue) to a Scala Value.

We usually write Reads as implicit objects. When our program finds that Reads implicit object in scope, our program will decode that JSON into a right type.

Automatic Reads for HelloWorld type:

1
implicit val reads = Json.reads[HelloWorld]

This is called “JSON Automated Mapping” for Reads. We don’t need to worry about mapping each and every property of a case class with property type. If we have any specific requirement or Play Framework does NOT automatic mapping for your types, then we can use “JSON Manual Mapping” as shown below:

Manual Reads for HelloWorld type:

1
2
3
4
implicit val reads:Reads[HelloWorld] = (
  (JsPath \ "module").read[String] and
  (JsPath \ "submodule").read[String]
)(HelloWorld.apply)

Here we have mapped both HelloWorld case class properties with property data type of String. As discussed in previous section, we use JsPath and “\” utilities to traverse each property.

We should specify HelloWorld.apply function to read each property one by one from the given JSON object and create an object of type HelloWorld.

5. Play JSON Writes Converter

In Play JSON API, Writes Converters are used to convert a Value ( in specific words, its a Scala Value or Scala Object or Scala Type) to a JsValue. Writes is also defined as a trait in play.api.libs.json package.

Here we can also use other words instead of “convert” word. It encodes or serialises or converts a Scala Value to a JsValue as shown in the below diagram.

Play JSON Writes Converter

So Writes converter is also know as “Serialiser” as it serialises a Scala Value into a JSON type (JsValue).

Like Reads, we usually write Writes as implicit objects. When our program finds that Writes implicit object in scope, our program will encode that Scala type into a JSON.

Automatic Writes for HelloWorld type:

1
implicit val writes = Json.writes[HelloWorld]

This is called “JSON Automated Mapping” for Writes. We can also write “JSON Manual Mapping” as shown below:

Manual Writes for HelloWorld type:

1
2
3
4
implicit val writes:Writes[HelloWorld] = (
  (JsPath \ "module").write[String] and
  (JsPath \ "submodule").write[String]
)(unlift(HelloWorld.unapply))

Here we have mapped both HelloWorld case class properties with property data type of String. We should specify HelloWorld.unapply function to extract each and every property of type HelloWorld into a JSON object. So far good, we use apply function for Reads and unapply function for Writes. What about that “unlift“? Good question!😊

Let us discuss it now.

First of all, assume that our HelloWorld case class is saved into HelloWorld.scala file. Please compile it, then observe the generated Java code as shown below (extracted only required code snippet):

1
2
3
4
5
6
public class HelloWorld implements Product, Serializable {
  // Other code
  public static Option<Tuple2> unapply(HelloWorld);
  public static HelloWorld apply(String, String);
  // Other code
}

Here we can observe that our HelloWorld case class contains both apply and unapply functions. As we know, HelloWorld case class contains two properties and both are of type String.

Well, apply function takes right parameters types: String, String like HelloWorld apply(String, String). However, if we observe the return type or result type of unapply function, its NOT String, String like Option<Tuple2> unapply(HelloWorld). Its returning Option of (String,String), but should be (String,String) to work Writes converter properly with unapply function. To remove this extra Option type, we use unlift function available in play.api.libs.functional.syntax package object.

I hope you understand it very well.

6. Play JSON Format Converter

In Play JSON API, Format Converters are used to convert a JsValue to a Scala Type or vice versa (that is from a Scala Type to a JsValue). In simple words, Play JSON Format converter contains both Reads and Writes converters that is Format = Reads + Writes as shown below.

Play JSON Format = Reads + Writes

In other way, we can represent this Format converter as shown below:

Play JSON Format Converter

Like Reads and Writes, Format is also defined as a trait in play.api.libs.json package.

Here we can also use other words instead of “convert” word. It encodes and decodes or serialises and deserialises or converts a Scala type to a JsValue and vice versa as shown in the below diagram.

Like Reads and Writes, we usually write Format as implicit objects. When our program finds that Format implicit object in scope, our program will encode that Scala type into a JSON or decode a JSON into a Scala type.

Automatic Format for HelloWorld type:

1
implicit val format = Json.format[HelloWorld]

Manual Format for HelloWorld type:

1
2
3
4
implicit val format: Format[HelloWorld] = (
    (JsPath \ "module").format[String] and
    (JsPath \ "submodule").format[String]
  )(HelloWorld.apply, unlift(HelloWorld.unapply))

As Format is a mix of Reads and Writes, we have defined our format implicit object by using both apply and unapply functions.

Sometimes, if we have Reads and Writes implicit objects separately as shown below:

Manual Reads for HelloWorld type:

1
2
3
4
implicit val readsHelloWorld: Reads[HelloWorld] = (
    (JsPath \ "module").read[String] and
    (JsPath \ "submodule").read[String]
  )(HelloWorld.apply)

Manual Writes for HelloWorld type:

1
2
3
4
implicit val writesHelloWorld: Writes[HelloWorld] = (
    (JsPath \ "module").write[String] and
    (JsPath \ "submodule").write[String]
  )(unlift(HelloWorld.unapply))

then we can write Format converter as shown below:

Manual Format for HelloWorld type using Reads and Writes:

1
implicit val format: Format[HelloWorld] = Format[readsHelloWorld, writesHelloWorld]

The play.api.libs.json package defines an alias for JsPath: __ (double underscore). We can use this if we prefer:

1
2
3
4
implicit val writesHelloWorld: Writes[HelloWorld] = (
    (__ \ "module").write[String] and
    (__ \ "submodule").write[String]
  )(unlift(HelloWorld.unapply))

NOTE: In post, to define converters I have used “Value” as Scala Value. But it can be anything based on language we use it. For instance, if we use them in Java, this “Value” means “Java Value”.

That’s all about three Play Framework’s Converters or Combinators. Play Framework source code defined them as Macros.

7. Play JSON Scala HelloWorld Example

So far, we have discussed theory enough theory about Play JSON Module. Its time to start developing a simple and basic HelloWorld example using Play Framework, Play JSON Module and Scala.

We are going to use IntelliJ IDE and SBT build tool to develop this application. If you are using IntelliJ IDE Ultimate Edition, first please create a Play Framework web application using IDE. If you are using IntelliJ IDE CE (Community Edition), please download the Play Scala Starter project from the following Lightbend’s Play Framework Examples GitHub location:
https://github.com/playframework/play-scala-starter-example

I have renamed this project as “PlayJSONScalaHelloWorldExample”, imported into IntelliJ IDE and deleted all files.

Then please continue the following steps to develop our HelloWorld application:

    • Add SBT Play Framework plugin to “plugins.sbt” file as shown below:

plugins.sbt

1
addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.6.17")

In my previous two posts, I was using Play Framework SBT plugin version “2.6.13”. Please follow Play Framework blog at https://blog.playframework.com for regular release updates.

    • Add Play JSON library dependency in “build.sbt” file as shown below:

build.sbt

01
02
03
04
05
06
07
08
09
10
11
name := "PlayJSONScalaHelloWorldExample"
version := "1.0.0"
lazy val root = (project in file(".")).enablePlugins(PlayScala)
scalaVersion := "2.12.6"
libraryDependencies ++= Seq(guice)
libraryDependencies += "com.typesafe.play" %% "play-json" % "2.6.9"

Description:

      • Play Framework has it’s JSON module with “play-json” name
      • Current latest version is 2.6.9
      • We need to append our project’s library dependencies to libraryDependencies SBT variable
    • Add a Play Route to “routes” file as shown below:

routes

1
2
## Hello Play JSON Controller
GET   /hello/:module  controllers.HelloWorldJSONController.hello(module: String)

Here we have mapped “/hello/:module” URI to HelloWorldJSONController.hello function. That means when User accesses our application with something like http://localhost:9000/hello/json, that request is served by this hello function.

    • Develop HelloWorld Data Model with Play JSON format in companion object as shown below:

HelloWorld.scala

1
2
3
4
5
6
7
8
package models
import play.api.libs.json.Json
case class HelloWorld(module:String)
object HelloWorld {
  implicit val writes = Json.writes[HelloWorld]
}

Description:

      • Case class is taking a String parameter to represent Play Framework module name.
      • HelloWorld companion object defines the following Play Framework Writes as implicit object:
1
implicit val writes = Json.writes[HelloWorld]

As discussed, Play Framework’s Writes converter is used to convert a Value (Scala Type or Value) into a JSON value (JsValue).

    • Develop hello function in HelloWorldJSONController controller as shown below:

HelloWorldJSONController.scala

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
package controllers
import javax.inject.Inject
import models.HelloWorld
import play.api.libs.json.Json._
import play.api.mvc.InjectedController
class HelloWorldJSONController @Inject() extends InjectedController {
  def hello(module: String) = Action {
    Ok(toJson(HelloWorld(module)))
  }
}

Description:

      • Like previous examples, we have developed an example by extending InjectedController and using @Inject annotation
      • Unlike previous examples, hello Action or function is NOT using any Scala View Template to serve response back to the End User. It’s directly sending HelloWorld Case class as Play Results to End User as shown below:
1
Ok(toJson(HelloWorld(module)))

Here Play Framework Results means OK Status which Generates a ‘200 OK’ result.

      • We are NOT sending HelloWorld Case class as it is. First, it’s converting into a JSON object by using Json.toJson() function as shown below:
1
Json.toJson(HelloWorld(module))

As discussed in the previous sections, toJson function is used to convert a Scala Object into a JSON Object. Let us observe the JSON response in the coming sub-section.

      • Json companion object defines this toJson function as shown below:
1
2
3
4
5
object Json {
def toJson[T](t: T)(implicit obj: Writes[T]): JsValue = obj.writes(t)
}

The return type of toJson function is JsValue. As discussed, JsValue is super type of all Play JSON API and is generic JSON value type.

We will try to develop another Endpoint for same functionality using Scala View Template soon.

7.1 Test Play JSON HelloWorld Example

In this section, we will test Play JSON HelloWorld example developed in the previous section. Please do the following steps one by one:

    • To up and run our application, please execute the following sbt command
1
2
$cd PlayJSONScalaHelloWorldExample
$sbt run
    • Access http://localhost:9000/hello/json url from web browser as shown below and observe the result

Test Play JOSN + Scala HelloWorld Example with Browser

7.2 Play JSON HelloWorld without Json.toJson

If we observe our previous Play JSON HelloWorld Example, our HelloWorldJSONController controller converts HelloWorld Scala object to JsValue using Json.toJson() utility and sends thats response back to End User to render it on a Web Browser. It was working fine.

What will happen if we send that HelloWorld Scala object as is? Please do the following changes to our controller:

HelloWorldJSONController.scala

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
package controllers
import javax.inject.Inject
import models.HelloWorld
import play.api.libs.json.Json._
import play.api.mvc.InjectedController
class HelloWorldJSONController @Inject() extends InjectedController {
  def hello(module: String) = Action {
    Ok(HelloWorld(module))
  }
}

Here we just removed the Json.toJson() function call in hello Action. Please access the same url http://localhost:9000/hello/json from web browser as shown below and observe the results:

Play JSON + Scala HelloWorld Error Scenario

Here if we can observe the error message, it clearly says that we need to develop a “Writeable[models.HelloWorld]”. We will discuss about Writeable in a separate post.

7.3 Play JSON HelloWorld Example with View Template

If we observe our main Play JSON HelloWorld Example, we can say that our Controller has not used Scala View Template to render the response. It just converts our Data model into JSON and sends that JSON to the End user directly.

In this section, we will do the same functionality by using Scala View Template. Please do the following steps to experiment this scenario:

    • Develop new End point in routing file as shown below:

routes

1
2
3
## Hello Play JSON Controller
GET   /hello/:module  controllers.HelloWorldJSONController.hello(module: String)
GET   /hello/view/:module  controllers.HelloWorldJSONController.helloView(module: String)

Here we have added /hello/view/:module End point to map this request to HelloWorldJSONController.helloView() Action.

    • Develop Scala View Template as shown below:

hello.scala.html

1
2
3
@(module: String)
<h1>Play JSON + Scala Example</h1>
<h2>@module</h2>
    • Develop new Action helloView() in our Controller as shown below:

HelloWorldJSONController.scala

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
package controllers
import javax.inject.Inject
import models.HelloWorld
import play.api.libs.json.Json._
import play.api.mvc.InjectedController
class HelloWorldJSONController @Inject() extends InjectedController {
  def hello(module: String) = Action {
    Ok(toJson(HelloWorld(module)))
  }
  def helloView(module: String) = Action {
    Ok(views.html.hello(stringify(toJson(HelloWorld(module)))))
  }
}

Description:

      • Here we have develop new Action: helloView by using hello Scala View Template
      • In first step, we are converting HelloWorld data model to JSON using Json.toJson() function
      • The return type or type annotation of Json.toJson() function is JsValue
      • However, our hello view template takes String as a parameter so we should convert this JsValue to String
1
@(module: String)
      • We are using Json. stringify() function to convert that JsValue to String as shown below:
1
2
3
4
5
def helloView(module: String) = Action {
  Ok(views.html.hello(Json.stringify(Json.toJson(HelloWorld(module)))))
}
    • Make sure our server is up and running.
    • Please access the same url http://localhost:9000/hello/view/json from web browser as shown below and observe the results:

Play JSON + Scala HelloWorld with Scala Template

That’s it about Play JSON + Scala HelloWorld Basic Example. Let us explore Play Framework JSON module few more details with one more example in the coming section.

8. Play JSON Scala Complex Example

In previous section, we have developed a basic, simple and easy to understand Play JSON HelloWorld example using Writes converter only. Here we are going to develop another example to explore all 3 converters: Reads, Writes and Format using Play Framework, Play JSON Module and Scala.

We are going to use IntelliJ IDE and SBT build tool to develop this application. If you are using IntelliJ IDE Ultimate Edition, first please create a Play Framework web application using IDE. If you are using IntelliJ IDE CE (Community Edition), please download the Play Scala Starter project from the following Lightbend’s Play Framework Examples GitHub location:
https://github.com/playframework/play-scala-starter-example

I have renamed this project as “PlayJSONScalaBooksExample”, imported into IntelliJ IDE and deleted all files.

Then please continue the following steps to develop our HelloWorld application:

    • First couple of steps are same as our Play JSON HelloWorld example
    • Develop our Book data model as shown below:

Book.scala

1
2
3
4
5
6
7
8
package models
import play.api.libs.json.Json
case class Book(isbn: String, title: String, author: String, noofpages: Int, price: Double)
object Book {
  implicit val format = Json.format[Book]
}

Here we are using Play Framework’s Format converter. If required, we can write manual Reads and Writes as shown below:

Book.scala

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
package models
import play.api.libs.json.Json
case class Book(isbn: String, title: String, author: String, noofpages: Int, price: Double)
object Book {
    implicit val reads: Reads[Book] = (
      (JsPath \ "isbn").read[String] and
      (JsPath \ "title").read[String] and
      (JsPath \ "author").read[String] and
      (JsPath \ "noofpages").read[Int] and
      (JsPath \ "price").read[Double]
    )(Book.apply _)
  implicit val writes: Writes[Book] = (
      (JsPath \ "isbn").write[String] and
      (JsPath \ "title").write[String] and
      (JsPath \ "author").write[String] and
      (JsPath \ "noofpages").write[Int] and
      (JsPath \ "price").write[Double]
    )(unlift(Book.unapply))
}
    • Develop service for Book domain model as shown below:

BookService.scala

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package services
import models.Book
class BookService {
  def getBooks(): List[Book] = books
  def getBook(isbn: String): Option[Book] = {
    val mybook = books.filter{ book =>
      book.isbn == isbn
    }
    mybook.headOption
  }
  def addBook(book: Book) = {
    books :+= book
    books
  }
  var books:List[Book] = List[Book](
    Book("ISBN01","Scala Reactive Programming", "Rambabu Posa", 550, 35.50),
    Book("ISBN02","Scala 2.13 In Depth", "Lokesh Posa", 420, 25.50),
    Book("ISBN03","Play JSON In Practice", "Rams", 510, 31.50),
    Book("ISBN05","Scala In Depth", "Rambabu Posa", 750, 38.90)
  )
}

Here we have hardcoded couple of Books list for out testing purpose. When we discuss about “Play Framework + Scala + Database Example”, we will try to store this data some where in Relational Database or NoSQL Data store.

    • Develop Scala View temple to display Book results as JSON output as shown below:

books.scala.html

1
2
@(book: String)
@book
    • Develop controller for Book domain model as shown below:

BookStoreController.scala

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package controllers
import javax.inject.Inject
import models.Book
import play.api.libs.json.Json._
import play.api.mvc.InjectedController
import services.BookService
class BookStoreController @Inject()(bookService: BookService) extends InjectedController {
  def getBooks() = Action {
    val books = bookService.getBooks()
    Ok(views.html.books(stringify(toJson(books))))
  }
  def getBook(isbn: String) = Action {
    val book = bookService.getBook(isbn)
    Ok(views.html.books(stringify(toJson(book))))
  }
  def addBook = Action(parse.json) { implicit request =>
    val newBook = request.body.as[Book]
    val books = bookService.addBook(newBook)
    Ok(views.html.books(stringify(toJson(books))))
  }
}

Please observe the following two lines of code:

1
2
3
def addBook = Action(parse.json) { implicit request =>
  val newBook = request.body.as[Book]
}

First point, we should understand is implicit request object. To understand this, we should discuss the following two questions:

      • What does it really contain?
      • Why do we need this?

Answer to first question is that it contains User Request information like body or header. In our example, when User sent a POST request with Book information (see screenshots to understand it very well), this request implicit object’s body contains that Book information.

The Answer to the second question is that if we want to retrieve that Book information form User Request body, we should use this implicit request object. We can use it without implicit object also as shown below:

1
2
3
def addBook = Action(parse.json) { request =>
  val newBook = request.body.as[Book]
}

In our case, it works fine (test it by updating this example). However, Play Framework team (Lightbend) recommends to use this request object as implicit so that if any of User components or Play Framework components needs it as implicit, our application does NOT complain any errors.

In our example, we have retrieved our Book information using request.body.as[Book] code.

    • Define routes to Book domain model as shown below:

routes

1
2
3
4
## BookStore Play JSON Controller
GET   /books/:isbn  controllers.BookStoreController.getBook(isbn: String)
GET   /books        controllers.BookStoreController.getBooks()
POST  /books        controllers.BookStoreController.addBook()
    • Make sure this application is up and running.
    • Please access http://localhost:9000/books url to observe the available Books list from our BookStore as shown below:

Get all Books available in BookStore

    • Please access http://localhost:9000/books url with Book details to add new Book to existing Book list of our BookStore as shown below:

Add new Book to our BookStore

    • Please access http://localhost:9000/books/ISBN04 url to observe the details of our newly added Book from our BookStore as shown below:

Get New Book Details

9. Conclusion

One of the best features of Play! Framework is that it supports REST API by design. It has a separate JSON module “play-son” to develop RESTful Web services easily. As its an independent module, we can use it not only in Play Framework, in any other web frameworks or standalone applications too.

Play JSON API defines required JSON types and some utilities to take care of supporting JSON API in Play Framework. It has 3 combinators: Reads, Writes and Format to ease the process of converting Scala Values to JsValues and vice versa.

We have developed two simple and easy to understand Play JSON examples in Scala language using SBT build tool. Please go through the Play JSON module source code to understand this API in-depth.

10. References

If you are interested to learn more details about Play Framework, Play JSON, Scala Language and SBT tool, please refer the following important websites:

11. Download the Source Code

That was a Play! Framework JSON & Scala Web Application Example Tutorial.

Download
You can download the full source code of this example here: PlayFramework + PlayJSON + Scala Examples

Rambabu Posa

Ram did his Masters in IS(Information Systems) from Andhra University, India. He has 18+ years of IT Experience: 10+ years of experience in Java Ecosystem and 8+ years of experience in Data Engineer workd(Scala/Python/Java/Go, BigData, GCP, AWS, AZure,Terraform, Airflow). He is author of “Scala Reactive Programming” book. Apart from Java, Python and Scala, he is good at Spark, PySpark, Scio/Flight, Apache BEAM, REST API, NoSQL, BigData Hadoop Stack, Cloud, Groovy, Play Framework, Akka Toolkit, Kafka, Kubernetes (K8S), TDD, BDD,Agile and much more. He likes sharing his knowledge through writing tutorials and books.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

2 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Viru
Viru
5 years ago

very well written !

Nagendra varma
Nagendra varma
4 years ago

In Point 4, below the image it should be

“So Reads converter is also know as “Deserialiser” ……..” instead of
“So Writes converter is also know as “Deserialiser” ……..”

Back to top button