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.
Table Of Contents
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:
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.
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.
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.
In other way, we can represent this Format converter as shown below:
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 JSONformat
in companion object as shown below:
- Develop
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 inHelloWorldJSONController
controller as shown below:
- Develop
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 sendingHelloWorld
Case class as Play Results to End User as shown below:
- Like previous examples, we have developed an example by extending
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 usingJson.toJson()
function as shown below:
- We are NOT sending
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 thistoJson
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
- Access
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:
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:
- Develop new Action
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 usinghello
Scala View Template - In first step, we are converting
HelloWorld
data model to JSON usingJson.toJson()
function - The return type or type annotation of
Json.toJson()
function isJsValue
- However, our hello view template takes String as a parameter so we should convert this
JsValue
to String
- Here we have develop new Action:
1 | @(module: String) |
- We are using
Json. stringify()
function to convert that JsValue to String as shown below:
- We are using
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:
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:
- Please access
http://localhost:9000/books
url with Book details to add new Book to existing Book list of our BookStore as shown below:
- Please access
- Please access
http://localhost:9000/books/ISBN04
url to observe the details of our newly added Book from our BookStore as shown below:
- Please access
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:
- Play Framework website: https://www.playframework.com
- Play Framework Scala API: https://www.playframework.com/documentation/2.6.x/api/scala/index.html#package
- Play Framework Scala JSON API: https://www.playframework.com/documentation/2.6.x/ScalaJson
- Play JSON Module source code: https://github.com/playframework/play-json
- Scala Language: https://www.scala-lang.org
- Scala API: https://www.scala-lang.org/api/2.12.6
- Scala SBT tool: https://www.scala-sbt.org
11. Download the Source Code
That was a Play! Framework JSON & Scala Web Application Example Tutorial.
You can download the full source code of this example here: PlayFramework + PlayJSON + Scala Examples
very well written !
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” ……..”