Finch框架中如何为jsonBody应用ValidationRule校验规则?
jsonBody[User] in Finch Got it, let's walk through how to adapt your existing validation logic for param to work with jsonBody[User] in Finch. The core idea is to either validate the entire parsed User instance or target specific fields after (or during) JSON deserialization.
Option 1: Validate the Entire User Instance
First, you can reuse your existing mailRule and wrap it into a ValidationRule[User] that checks the email field of the parsed User. Then apply this rule directly to jsonBody[User] using the should method:
case class User(name: String, age: Int, email: String) // Your existing email validation rule val mailRule = ValidationRule[String]("mail should be a valid email") { email => """(\w+)@([\w\.]+)""".r.unapplySeq(email).isDefined } // Create a validation rule for the full User instance val userValidationRule = ValidationRule[User]("invalid user: email is not valid") { user => mailRule(user.email).isValid } // Apply the rule to jsonBody val userJson: Endpoint[User] = jsonBody[User].should(userValidationRule) // Example endpoint using the validated jsonBody val createUserEndpoint: Endpoint[User] = post("users" :: userJson) { user: User => Ok(user) // Respond with the valid user if all checks pass }
Option 2: Granular Field Validation with andThen
If you prefer to handle field validation more explicitly, you can use andThen to chain the JSON parsing with field-level validation. This approach lets you return specific errors for each field:
val userJson: Endpoint[User] = jsonBody[User].andThen { user => mailRule(user.email) // Validate the email field .map(_ => user) // Return the valid User if validation passes }
Adding Multiple Validation Rules
If you need to validate multiple fields (like age being positive), you can combine rules using a for-comprehension for cleaner code:
// Add an age validation rule val ageRule = ValidationRule[Int]("age must be a positive number")(_ > 0) // Combine email and age rules into a single User validation val combinedUserRule = for { _ <- mailRule.contramap[User](_.email) // Map User to its email field for validation _ <- ageRule.contramap[User](_.age) // Map User to its age field } yield () val userJson: Endpoint[User] = jsonBody[User].should(combinedUserRule)
How It Works
When a client sends an invalid JSON payload (e.g., an email without @), Finch will automatically return a FinchError with your custom error message, just like it does with invalid param values. This keeps your validation behavior consistent across query params and JSON bodies.
内容的提问来源于stack exchange,提问作者hyogo0212

