This is a study note for Play JSON and Play WS.
1 Play JSON
The play.api.libs.json
package contains JSON-related data structures and utilities to convert JSON data. It supports automatic parsing and automatic conversion.
The JsValue
trait represents a JSON value that could be one of JsString
, JsNumber
, JsBoolean
, JsObject
, JsArray
and JsNull
. The Json
object provides utilities providing conversion to and from JsValue
. The JsPath
represent a path into a JsValue
structure, like the XPath for XML.
Use Json.parse()
to parse a string into a JsValue
. Use JsObject()
, Json.obj()
or Json.arr
to construct a JSON object.
1.1 Convert to JsValue
The Json.toJson[T](T)(implicit writes: Writes[T])
converts a Scala value to JsValue
. Writes[T]
converts a value of T
to JsValue
. The Play JSON API comes with implicit Writes
for basic types such as Int
, String
, and Boolean
ect. It also support for collections, such as Seq
and List
, of any type T
that a Writes[T]
exists.
1.2 Traverse a JsValue
Structure
Use the \
operator to access a property of a JsValue
or an indexed value in JsArray
. The \
operator returs a JsLookupResult
that is either a JsDefined
or JsUndefined
.
Use \\
operator to lookup for the field in the current object and all descendants.
1.3 Convert from a JsValue
Json.stringify()
or Json.prettyPring()
return a string from a JsValue
.
Use JsValue.as[T](implicit fjs: Reads[T]): T
to convert a JsValue
to a value of type T
. Reads[T]
convert a JsValue
to T
. The JSON API provides Reads
for basic types.
Use JsValue.asOpt
to return an Option[T]
.
Use JsValue.validate
to validate and convert from a JsValue
. The result is a type of JsResult
that could be JsSuccess
or JsError
. the JsResult
has methods such as getOrElse
, map
, and fold
.
To covert a JsValue
to model, you need to define a Reads[T]
.
1.4 JSON with HTTP
To send JSON data, convert model data to JsValue
using Json.toJson()
method. For received data with text/json
or application/json
headers, Play uses a JSON BodyParser
that generates a JsValue
.
1.5 JSON Reads/Writes/Format Combinators
JsPath
supports three path types:
- simple path: `JsPath \ “location” \ “lat”
- recursive path:
JsPath \\ "name"
- indexed path:
(JsPath \ "residents")(0)
JsPath
has JsPath.read[T](implicit r: Reads[T]): Reads[T]
and JsPath.readNullable[T](implicit r: Reads[T]): Reads[Option[T]]
methods to create special Reads
. Use and
, keepAnd
and andKeep
combinators to combine different parts and returns a FunctionalBuilder
. Use the builder’s apply
with a model’s apply _
.
Similarly, the write[T]
method uses the and
combinator to create a builder and finally calls unlift(Model.unapply)
.
Use lazyRead
and lazyWrite
to handle recursive types.
Format[T]
is a mix of the Read
and Writes
. It is used for implicit conversion in place of its components.
1.6 Auto Mapping
Json.reads[T]
, Json.writes[T]
and Json.format[T]
are macros that can be used to generate Reads[T]
, Writes[T]
and Format[T]
. It is done at compile-time.
Json.valueReads[T]
, Json.valueWrites[T]
, and Json.valueFormat[T]
are used for value classes.
To be able to access JSON from request.body.asJson
, the request must have a Content-Type header of application/json
. You can relax this constraint by using the tolerantJson
body parser.
2 Play WS
For compile time DI, use AhcWSComponents
. Use an instance of WSClient
to build a request with various HTTP options. Following is an example:
|
|
To add cookies, use addCookies
method with values of DefaultWSCookie
or play.api.mvc.Cookie
.
The get()
and post()
method will send the request and return a Future[WSResponse]
. To Post url-form-encoded data, use Map[String, Seq[String]]
as body. If the body is empty, use play.api.libs.ws.EmptyBody
.
Use the map
method to process Future[WSResponse]
. An implicit execution context must be available to process the result. The WSResponse
extends play.api.libs.ws.WSBodyReadables
trait that contains a type class for Play JSON conversion. For example, map { response => (response.json \ "person" \ "name").as[String]
. For auto mapping, use validate[T]
to create a Future[JsResult[T]]
.