Home

Awesome

Build status codecov License

Play API Refined

A tiny library to generate OpenAPI documentation and json schema based on Refined's case classes.

Setup

In order to use play-json-org.dgouyette.refined you need to add the following lines to your build.sbt:

resolvers += Resolver.bintrayRepo("dgouyette", "maven")

libraryDependencies += "org.dgouyette" %% "api-refiner" % "1.0.0-M1"

Usage

Play Json Refined errors

To return json errors based on org.dgouyette.refined classes you must import :

import org.org.dgouyette.json.RefinedRuntimeValidator._

Json Schema generation


case class CollectionStringNonEmpty(e : List[String] Refined NonEmpty)
JsonSchema.asJsValue[CollectionStringNonEmpty] // => {"e":{"minLength":1,"type":"array","items":{"type":"string"}}}

Json Schema on Client Error

case class LoginDTO(email  : String Refined NonEmpty, password : String Refined NonEmpty)


@Singleton
class HomeController @Inject()(bp: BodyParserWithJsonSchema) extends AbstractController(cc) {
  implicit val loginSchema = JsonSchema.asJsValue[LoginDTO]
  implicit val dtoSchema = JsonSchema.asJsValue[SimpleDTO]
  
  def login(): Action[LoginDTO] = Action(bp.jsonRefined(LoginDTO.fmt, loginSchema)) {
    implicit request =>
    Ok
  }
}

With a bad client request :

curl -X POST http://localhost:9000/login -d '{"email" :"","password" :"" }'

You will have this error

{
    "obj.email": [
        {
            "msg": [
                "Predicate isEmpty() did not fail."
            ],
            "args": []
        }
    ],
    "_schema": {
        "password": {
            "minLength": 1,
            "type": "string"
        },
        "email": {
            "minLength": 1,
            "type": "string"
        }
    },
    "obj.password": [
        {
            "msg": [
                "Predicate isEmpty() did not fail."
            ],
            "args": []
        }
    ]
}

Generate OpenAPI (Swagger) Documentation

OpenAPIController :

def json: Action[Unit] = Action(parse.empty) {
    implicit  req =>
     Ok(OpenAPI.fromRoutesFile("conf/routes"))
  }

conf/routes

POST        /login                           controllers.HomeController.login
GET         /doc/json                        controllers.OpenAPIController.json

OpenAPI Documentation