A Mason library for scala

scala-mason is a library for Mason format based on play-json.

What is Mason ?

Mason is a format describing hypermedia links inside a JSON object.

For more information, please visit https://github.com/JornWildt/Mason

Getting started

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.

Scope of scala-mason

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).

How to use scala-mason ?

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 } } }