In Spray, you get a lot of input validations for free. If you have a model like this:

object RobotProtocol extends DefaultJsonProtocol {
  case class Robot(name: String, amountOfArms: Int)
  implicit val RobotFormat = jsonFormat2(Robot)
}

See here for the whole example. All the attributes are required. So if you try to post a robot without a name.

{
  "amountOfArms": 2
}

You'll get http 400 with this message:

The request content was malformed:
Object is missing required member 'name'

The types are also checked.

{
  "name": "C3PO",
  "amountOfArms": "two"
}

returns

The request content was malformed:
Expected Int as JsNumber, but got "two"

It is possible to make a value optional with Option.

case class Robot(name: String, color: Option[String], amountOfArms: Int)

And we can add extra requirements with 'require'. In the second parameter we can write a nice readable message.

object RobotProtocol extends DefaultJsonProtocol {
  case class Robot(name: String, color: Option[String], amountOfArms: Int) {
    require(amountOfArms >= 0, "Robots cannot have a negative amount of arms!")
  }
  implicit val RobotFormat = jsonFormat3(Robot)
}

Now when we post an impossible robot.

{
  "name": "C3PO",
  "amountOfArms": -1
}

We get a nice error message.

The request content was malformed:
requirement failed: Robots cannot have a negative amount of arms!

This way you can make as complex and informative as you want.

shadow-left