Say I have a User
model that is an input to my server:
case class User(name: String, age: Int)
object User:
val validator: Validator.Custom[User] =
Validator.Custom[User] { u =>
if u.age < 0 then
Invalid("Age must be greater than or equal to 0")
else
Valid
}
And I want to validate json input that the age is greater than 0, I could do this when defining my endpoint:
private val jsonBodyExample: SyncEndpoint = endpoint
.post
.in("hello")
.in(jsonBody[User].validate(User.validator))
.out(stringBody)
.handleSuccess(user => s"Hello ${user.name} who is ${user.age} years old")
But we can’t rely on every endpoint remembering to explicitly declare this validator. The docs seem to indicate that you can do this by providing a Codec
:
given Codec[String, User, JsonSomething?] = ???
Am I reading that correctly? If so, then how do I construct a Codec given I already have a validator defined?
If not, then maybe I just need to define an alternative to jsonBody[User]
… something like
def validatedJsonBody[T: Encoder: Decoder: Schema]: EndpointIO.Body[String, T] =
jsonBody[User].validate(_.validator)
Feels a little icky, but maybe the right way?