[英]Buisness logic error handling in scala
我正在使用Scala和Play Framework 2.5開發Web服務。 我的應用程序具有典型的分層體系結構。 我有以下類: model.User
, repository.UserRepository
, service.UserService
和controllers.UserController
,我正在嘗試一種無需使用Exception
即可處理業務邏輯錯誤的好方法。
考慮以下情況:收到了注冊新用戶的請求。 請求正文中有兩個參數: email
和password
。 這些參數被饋送到UserService#registerUser
,后者檢查電子郵件是否有效以及使用該電子郵件的用戶是否已經存在。 我的解決方案是使UserService#registerUser
返回Either[BuisnessFailure, Int]
對象。 BuisnessFailure
是一個特征,由WrongEmailFormatFailure
和UserAlreadyExistFailure
繼承。 如果電子郵件無效,則UserService#registerUser
返回Left(WrongEmailFormatFailure)
。 如果已經存在使用此類電子郵件的用戶,則UserService#registerUser
返回Left(UserAlreadyExistFailure)
。 在成功的情況下, UserService#registerUser
返回Right(userRepository.create(User(email, password))
之后,在controllers.UserController
我可以使用模式匹配處理這種情況並發送適當的響應。
那么,這種方法足以應付類似的情況嗎? 請在下面找到我的代碼:
用戶:
package model
case class User(email: String, password: String)
UserRepository:
package repository
import model.User
class UserRepository {
def create(user: User): Int = ???
def find(email: String): Option[User] = ???
}
UserService:
package service
import model.User
import repository.UserRepository
import util.{BuisnessFailure, UserAlreadyExistFailure, WrongEmailFormatFailure}
class UserService {
private val userRepository: UserRepository = ???
def registerUser(email: String, password: String): Either[BuisnessFailure, Int] = {
if (userAlreadyExists(email))
Left(UserAlreadyExistFailure)
else
if (!isEmailValid(email))
Left(WrongEmailFormatFailure)
else
Right(userRepository.create(User(email, password)))
}
private def isEmailValid(email: String): Boolean = ???
private def userAlreadyExists(email: String): Boolean = ???
}
UserController的:
package controller
import service.UserService
import util.{UserAlreadyExistFailure, WrongEmailFormatFailure}
class UserController extends play.api.Controller {
private val userService = new UserService
def signUp() = Action(parse.json) { implicit request =>
//obtaining email and password parameters from request body
val email = ???
val password = ???
userService.registerUser(email, password) match {
case Left(WrongEmailFormatFailure) => // send 400 code and appropriate error message
case Left(UserAlreadyExistFailure) => // send 400 code and appropriate error message
case Right(_) => // send response with 200 code
}
}
}
BuisnessFailure:
package util
sealed trait BuisnessFailure
case object UserAlreadyExistFailure extends BuisnessFailure
case object WrongEmailFormatFailure extends BuisnessFailure
這正是我們為最大的項目之一進行錯誤處理時所做的事情,而我們沒有任何問題。 Either
都應完全那樣使用。 Left
表示錯誤, Right
表示結果。
唯一的一點是,由於大多數Scala應用程序都是非阻塞(異步)應用程序,因此人們將使用Future[Either[Error, Int]]
而不是Either[Error, Int]
。 但是還是可以的,因為每當您決定進行非阻塞時,您都可以輕松地將Either
包裝在Future
並且正如我告訴您的那樣,無需擔心並發問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.