Play! Scala case class validation - scala

I have a controller defined like this:
def registerCompany = Action.async(BodyParsers.parse.json) { request =>
request.body.validate[Company].fold(
errors => Future {
BadRequest(errors.mkString)
},
company => Future {
registrationService.registerCompany
Ok("saved")
}
)
}
Company is a simple case class
case class Company(name: String, address: Address, adminUser: Option[User] = None,
venues: Option[Set[Venue]] = None, _id: Option[Long]) {
}
so that I can take advantage of
implicit val companyFormatter = Json.format[Company]
So far so good, but now I want to have validation in the Company class. I've been googling a bit and the best I found was this:
http://koff.io/posts/292173-validation-in-scala/
So many solutions, yet, I'm not happy with any of them. Most of these solutions have known limitations or are a bit messy. I'd like to have declarative validation (annotation based), as that means I write less code and it looks cleaner.
I could mix java with scala and use JSR-303, but it doesn't work for case classes and I don't want to implement Reads and Writes for simple objects.
This is the closest I could find to what I want, but it doesn't support NotNull: https://github.com/bean-validation-scala/bean-validation-scala
Seems a bit like a luxury problem, with so many different solutions, but the truth is that in Java I can get the best of both worlds.
Is there anything else that I could use? Or any work around to the possibilities I'm listing here that could allow me to use both annotation based validation and case classes?

It all depends on what you mean by validation.
You gave an example of a validate Json in request body and I think you would like validate Json request (with Company constraints) but not case class Company (although the topic is called "Scala case class validation"). So you need use Validation with Reads
For example you may use:
( __ \ "name").read[String] for Required constraint.
( __ \ "_id").read[Long](min(0) keepAnd max(150)) for 0 < x < 150 constraint.
You may implement own Reads[Company] and Writes[Company] but not macros Json.format[Company]
Update for comment "The difference is that you rarely need to write a custom deserializer, as jackson knows how to handle any object"
If you don't want implement own deserialization and want use format macros, you may implement Company validation, but still using Reads:
val f(company: Company): Boolean = {... company constraints to boolean ...}
request.body.validate[Company](
companyFormatter.filter(ValidationError("Company validation error"))(f)
)
but this constraints will be applied after full Company deserialization.
Don't even know which is better: universal deserialization and "post" constraints or own deserialization and "pre" constraints. But both are working.

You could also roll your own, something like this:
https://gist.github.com/eirirlar/b40bd07a71044d3776bc069f210798c6
It will validate both case classes and incomplete case classes (hlists of options of types tagged with keys, where types and keys match the case class).
It won't give you annotations, but you're free to declare different validators for different contexts.

Related

How to use Scala Cats Validated the correct way?

Following is my use case
I am using Cats for validation of my config. My config file is in json.
I deserialize my config file to my case class Config using lift-json and then validate it using Cats. I am using this as a guide.
My motive for using Cats is to collect all errors iff present at time of validation.
My problem is the examples given in the guide, are of the type
case class Person(name: String, age: Int)
def validatePerson(name: String, age: Int): ValidationResult[Person] = {
(validateName(name),validate(age)).mapN(Person)
}
But in my case I already deserialized my config into my case class ( below is a sample ) and then I am passing it for validation
case class Config(source: List[String], dest: List[String], extra: List[String])
def vaildateConfig(config: Config): ValidationResult[Config] = {
(validateSource(config.source), validateDestination(config.dest))
.mapN { case _ => config }
}
The difference here is mapN { case _ => config }. As I already have a config if everything is valid I dont want to create the config anew from its members. This arises as I am passing config to validate function not it's members.
A person at my workplace told me this is not the correct way, as Cats Validated provides a way to construct an object if its members are valid. The object should not exist or should not be constructible if its members are invalid. Which makes complete sense to me.
So should I make any changes ? Is the above I'm doing acceptable ?
PS : The above Config is just an example, my real config can have other case classes as its members which themselves can depend on other case classes.
One of the central goals of the kind of programming promoted by libraries like Cats is to make invalid states unrepresentable. In a perfect world, according to this philosophy, it would be impossible to create an instance of Config with invalid member data (through the use of a library like Refined, where complex constraints can be expressed in and tracked by the type system, or simply by hiding unsafe constructors). In a slightly less perfect world, it might still be possible to construct invalid instances of Config, but discouraged, e.g. through the use of safe constructors (like your validatePerson method for Person).
It sounds like you're in an even less perfect world where you have instances of Config that may or may not contain invalid data, and you want to validate them to get "new" instances of Config that you know are valid. This is totally possible, and in some cases reasonable, and your validateConfig method is a perfectly legitimate way to solve this problem, if you're stuck in that imperfect world.
The downside, though, is that the compiler can't track the difference between the already-validated Config instances and the not-yet-validated ones. You'll have Config instances floating around in your program, and if you want to know whether they've already been validated or not, you'll have to trace through all the places they could have come from. In some contexts this might be just fine, but for large or complex programs it's not ideal.
To sum up: ideally you'd validate Config instances whenever they are created (possibly even making it impossible to create invalid ones), so that you don't have to remember whether any given Config is good or not—the type system can remember for you. If that's not possible, because of e.g. APIs or definitions you don't control, or if it just seems too burdensome for a simple use case, what you're doing with validateConfig is totally reasonable.
As a footnote, since you say above that you're interested in looking in more detail at Refined, what it provides for you in a situation like this is a way to avoid even more functions of the shape A => ValidationResult[A]. Right now your validateName method, for example, probably takes a String and returns a ValidationResult[String]. You can make exactly the same argument against this signature as I have against Config => ValidationResult[Config] above—once you're working with the result (by mapping a function over the Validated or whatever), you just have a string, and the type doesn't tell you that it's already been validated.
What Refined allows you to do is write a method like this:
def validateName(in: String): ValidationResult[Refined[String, SomeProperty]] = ...
…where SomeProperty might specify a minimum length, or the fact that the string matches a particular regular expression, etc. The important point is that you're not validating a String and returning a String that only you know something about—you're validating a String and returning a String that the compiler knows something about (via the Refined[A, Prop] wrapper).
Again, this may be (okay, probably is) overkill for your use case—you just might find it nice to know that you can push this principle (tracking validation in types) even further down through your program.

Why doesn't scala have easier support for Equals?

Reading Martin's book, chapter about equality Object equality chapter one may notice that properly implementing equals in scala (as actually in any other language) is not very straightforward. However scala is extremely powerful and agile, and I cannot believe it could not simplify things a bit. I know that scala generates proper equals for case classes, so I wonder why couldn't it generate simplifications for normal classes?
To show my point, I wrote an example of how would I see this should look like. It probably has flaws, and I had to use ClassTag which I know is very wrong for such basic thing as equals due to performance (any tip how could I do it without ClassTag?), but thinking that scala can generate proper equals for case classes, I'd say it should be able to generate proper code for normal classes, giving that developer provides the Key which should be used to compare objects.
trait Equality[T] extends Equals {
val ttag: ClassTag[T]
def Key: Seq[Any]
def canEqual(other: Any): Boolean = other match {
case that: Equality[_] if that.ttag == ttag => true
case _ => false
}
override def equals(other: Any): Boolean =
other match {
case that: Equality[T] => canEqual(that) && Key == that.Key
case _ => false
}
override def hashCode = Key.foldLeft(1)((x, y) => 41 * x + y.hashCode)
}
Then you can use it like this:
class Point(val x: Int, val y: Int)(implicit val ttag: ClassTag[Point]) extends Equality[Point]{
override def Key: Seq[Any] = Seq(x, y)
}
I'm not very much into ClassTags, so I might have made it wrong, but it seems to be working. Still that's not what I am asking - I want to know is there any serious reasons, why scala itself do not simplify implementing equality checks?
It is an interesting idea, and I can see from a comment that scalaz has something like this. I'm not sure I have a complete answer, but some factors to consider are:
Case classes are a bit unique in that you're not supposed to inherit from them. Assuming they're not sub-classed, canEqual isn't even required.
There's something elegant about the idea that even '+' in scala is a function not a 'language feature.' It's not necessarily better to have this as a language feature instead of a library (and there are a number of utilities even in Java to help with implementing hashcode/equals). The existing "equals" method isn't a language feature, it's just a method on the parent class Object, inherited from Java.
Scala does still need to play-nice with Java, and that could be one barrier to radically changing how equals works. Interface requirements can't be imposed on existing Java classes that scala might want to inherit from.
When you do consider what the syntax might look like if it were a language feature, I'm not sure what could actually be eliminated or changed.
For example, the developer still has to specify the Key you suggest. Also, to be able to support, for example, anonymous subclasses and trait mix-ins where canEqual won't change, with a language feature you'd still need to explicitly define your class tag.
Maybe the analysis could be more interesting if you provide what, syntactically, it might look like if it were a language feature instead of a helper library. I might be missing some aspects of how this would work.
There is no such thing "proper equals" since it depends on the use cases.
For simple cases what you suggest may work, but in such case, using case class with also work. The problem is that while for simple Data classes it works, the same isn't true for other cases. For example, when there are inheritance - what is the right thing to do? if class have private members - does it should be part of the equals?? does public getters should be ? What will happen when when there are cyclic dependencies ?
One of the main reasons for the case classes cannot be inherit by other case class is the equality.

Idiomatic syntax for Option when the meaningful value is None

This is purely a coding-style question.
A function I'm calling returns an Option, and I want to take a specific action if it's equal to None.
Say, for example, that I'm trying to create a default user at boot time if it doesn't already exist. I'd call a function that attempts to find a user that matches the default one, and returns an Option[User].
If that return value is None, I'd like to run some user creation code. If not, I'm done.
I'm wondering what's the most idiomatic Scala syntax for this. What I have so far is:
def getUser(name: String): Option[User] = ...
getUser("admin") getOrElse createUser("admin", "ChangeThisNow!")
getUser("admin") match {
case None => createUser("admin", "ChangeThisNow!")
case _ =>
}
if(getUser("admin") == None) createUser("admin", "ChangeThisNow!")
The first solution seems like the most functional one, but I can't help but feel that there might be better ones - possibly by using partially applied functions, which I admit I'm still a bit fuzzy about.
Since in your case the goal is to cause a side effect, I'd use a conditional to stress that, instead of using getOrElse.
if (getUser("admin").isEmpty)
createUser("admin", "ChangeThisNow!")
Remember that scala is a multi-paradigm language.
In addition to syntax, you want to consider concepts such as cohesion (single responsibility) and so you can consider the composition of your objects in addition to the actual idioms you use in the syntax.
The OO way might be to decorate the object/class that getUser belongs to in to put that concern of creating the user in a wrapper so that other code that calls the getUser function never has to deal with that concern. This fits nicely with open/closed principle and single responsibility. This is a bit of an anemic domain model anti-pattern here but may show how OO can be used to extend the conversation into actual design.
Either pattern matching or getOrElse are reasonable solutions. Generally if statements aren't used against Monads like the option - at least not that I see.
Either way, I beleive the expression should return the result even if there are side effects (user creation).
case class User(name: String)
class UserService {
def getUser(name: String): Option[User] = ???
def createUser(name: String): User = ???
}
class UserServiceDecorator extends UserService {
override def getUser(name: String): Option[User] =
Some(super.getUser(name).getOrElse(super.createUser(name)))
}
Really the best way to do this is to assign the result to a meaningful variable name so your future code doesn't need to know if createUser was called or not.
val user = getUser("admin").getOrElse(createUser("admin", "ChangeThisNow!"))
This way you can use the user variable regardless of if you've created a new user or not.

Is this a good return-type pattern for designing Scala API's?

I see this type of pattern (found this example here) quite often in Scala:
class UserActor extends Actor {
def receive = {
case GetUser(id) =>
// load the user, reply with None or Some(user)
val user: Option[User] = ...
sender ! user
case FindAll() =>
// find all users
val users: List[User] = ...
sender ! users
case Save(user) =>
// persist the user
sender ! Right(user)
}
}
So depending on the call you get: Option[User], List[User], Right[User]. This approach is fine! I'm just asking out of interest if this is optimal? For example (and this may be a bad one): Will it make API's better or worse to try and generalise by always returning List[User]? So when a user is not found or if a save fails, then the list will simply be empty. I'm just curious.... any other suggestions on how the above 'pattern' may be improved?
I'm just trying to identify a perfect pattern for this style of API where you sometimes get one entity and sometimes none and sometimes a list of them. Is there a 'best' way to do this, or does everyone role their own?
The return types should help clarify your API's intended behavior.
If GetUser returned a List, developers might get confused and wonder if multiple users could possibly be returned. When they see that an Option is returned, they will immediately understand the intended behavior.
I once had to work with a fairly complex API which provided CRUD operations that had been generalized in the manner you describe. I found it to be difficult to understand, vaguely defined, and hard to work with.
In my opinion it is a very good pattern for API design.
I use very often Option as return type of my functions, if I want to return a single element, obviously because I don't need to deal with null. Returning a Seq is naturally for multiple elements and Either is optimal if you want to return a failure-description, I use it often while parsing I/O. Sometimes I even combine the Seq with one of the others. You likely don't know the preferences and goals of an user of your API, so it makes sence to provide all of these return-types to make the user feel as comfortable as possible.

mutually recursive types in scala

Is it possible to have mutual recursive types in scala?
I have a xml files with a list of bugtracker issues. It's raw data. The model has different issue-types like "tasks", "subtasks", "bug", "special-bug".
Now I want to parse my raw-data to a hierarchical structure of tasks and subtasks:
// data type for field contents
abstract class Field
case class Id(raw : string) extends Field
case class Status(raw : string) extends Field
...
// data type for primary model
abstract class Issue(id : String, ...)
case class Task(id : Id, status : Status ..., subtasks : List[Subtask] ) extends Issue(id, ...)
case class Subtask(id : Id, status : Status ..., parent: Task) extends Issue(id, ...)
I wonder if this mutual recursion is theoretically possible?
Second question:
I render the model to some wiki-markup. This works fine with an overloaded recursive render() : String in the class for the datatype. (Probably I should have a "Renderable" Superclass !?)
What would be the cleanest way for parsing, i.e. I'd like to have a recursive
fromXML : scala.xml.Elem => Issue / Field
Where would I put it? How would it look like? IIUC, the companion is autogenerated for case-classes so I cant add to it?
I have this e.g.:
def fromXml(e : Elem) = e match {
case <a>test</a> => Id("test")
case _ => Status("Pre-analysed")
}
But I failed to give the function a type. What is the type of that function ?
I also thought about passing the xml-elem directly to the constructor of the ADT, would that be clever? Or should I separate XML-parsing and model-creation ?
Jesus, after learning the scala basics and doing some scripts and functions (and thinking too much java), I finally understood how to write ADTs and can express myself nearly as in good old Haskell times :-)
A: Regarding the initialisation of immutable, mutually dependent classes, have a look at this question.
B: Regarding your question render: Foo => String function vs. Renderable superclass, this is IMHO more or less a design decision between a functional and an object-oriented approach. I personally don't think that one of them is superior to the other, it is just a matter of taste. The paper "Independently Extensible Solutions to the Expression Problem" has a nice comparison between the two, although in a slightly more elaborate context (it is a great read, however).
C: Companion objects are created by the compiler, but if you also specify a companion object, the compiler will merge the two.
D: In your current class hierarchy there is no non-trivial common supertype for Issue and Field, which makes it difficult to give a meaningful return type for fromXML. You could work with an Either[Issue, Field], though, but this looks fishy to me. In general, I would avoid mixing functions that are supposed to return full-fledged nodes (e.g., Task) with those that return "internal" nodes (e.g., Status).
E: Did you had a look at existing solutions, e.g. scalaxb? You can find more links here and here.