scala-mason is a library for Mason format based on play-json.
Mason is a format describing hypermedia links inside a JSON object.
For more information, please visit https://github.com/JornWildt/Mason
Add scala-mason as a dependency in your project
libraryDependencies += "io.github.schidaine" %% "scala-mason" % "1.2.2"Scala 2.12 and 2.13 are supported.
scala-mason 1.2.0 implements Mason with some restrictions:
- is focused on writing Mason (this lib will not help to consume Mason web API),
- following link properties are not yet supported : schema, schemaUrl, template, accept, files and alt,
- doesn't allow a json array as a root json element (whereas it should be valid if there is no Mason properties at root).
In Play Json, you define Writes (or Format) with an implicit value in the companion object of your resource.
With scala-mason, you will have to define MasonWrites in the same way.
A small DSL helps you, using $ and :=. See MasonKeyBuilder to see available property names.
API Documentation is available here : https://schidaine.github.io/scala-mason/api/latest/schidaine/mason/index.html
Example:
import play.api.libs.json._
import schidaine.mason._
case class MyObject(data: String)
object MyObject {
implicit val masonWrites = new MasonWrites[MyObject] {
def writes(o: MyObject) =
Namespaces("ns1" -> "https://localhost/rels") ++
Json.obj("object" -> o.data) ++
Controls(
"self" -> Link($.href := "https://localhost/my-object"),
"ns1:add-description" -> Link($.href := "https://localhost/my-object/descriptions", $.encoding := JSON)
)
}
}Then, use Mason object to manipulate a such resource:
import schidaine.mason.Mason
val o = MyObject("Tardis")
Mason.toJson(o)As soon as a MasonWrites[A] exists, a MasonWrites[Option[A]] also exists and Iterable[A] can be easily serialized given an array name.
See example below where a Play! application manages HTTP content negotiation:
import play.api.libs.json.Json
import play.api.mvc._
import schidaine.mason.Mason
class MyController(...) {
val masonMediaType = "application/vnd.mason+json"
val AcceptsMason = Accepting(masonMediaType)
def getOne(...) = {
val myObject = MyObject("something") // or Some(MyObject("something"))
...
request match {
case Accepts.Json() => Ok(Json.toJson(myObject))
case AcceptsMason() => Ok(Mason.toJson(myObject)).as(masonMediaType)
case _ => NotAcceptable
}
}
def getAll(...) = {
val objects: List[MyObject] = ...
...
request match {
case Accepts.Json() => Ok(Json.toJson(objects))
case AcceptsMason() => Ok(Mason.toJson(objects, "objects")).as(masonMediaType)
case _ => NotAcceptable
}
}
}