BFF+CoreService架构下DTO和VO的含义和使用方式
2026/7/8 2:25:05 网站建设 项目流程

1,BFF+CoreService的含义

BFF:BackEnd For FrontEnd

这是一个springboot服务,但是不同之处在于它是专门服务于前端的,意思是处理前端请求,然后调用CoreService的方法完成业务逻辑。

他更侧重于处理前端请求,更加具体的业务逻辑是CoreService在做。

以下是BFF的service层:可以看出确实是在转发请求到CoreService服务

//这是service层 @Service public class AuthServiceImpl implements AuthService { @Resource //引入的是User模块暴露的UserFeign类 private UserFeign userFeign; @Override public UserBaseLoginVO login(UserLoginRequestVO userLoginRequestVO) { //处理VO为DTO,方便后续服务的调用 UserLoginDTO userDTO = BeanUtil.copyProperties(userLoginRequestVO, UserLoginDTO.class); //调用User模块的login方法 UserLoginResponseDTO userLoginResponseDTO = userFeign.login(userDTO); //处理后return UserBaseLoginVO userLoginVO = new UserBaseLoginVO(); userLoginVO.setToken(userLoginResponseDTO.getToken()); userLoginVO.setInfoVO(BeanUtil.copyProperties(userLoginResponseDTO.getInfoVO(), UserBaseInfoVO.class)); return userLoginVO; } }

2,CoreService

核心业务服务

掌管了Entity机密的服务。

侧重于具体的业务实现,而不是Http协议。

返回值也不是R<T>了,而是更加具体的对象

以下是一个服务的示例:这个服务用于实现登录业务,里面是具体的数据库表操作和逻辑处理。

@Service public class UserServiceImpl extends ServiceImpl<UserMapper, UserEntity> implements UserFeign { @Resource private JwtUtil jwtUtil; @Override public UserLoginResponseDTO login(UserLoginDTO userLoginDTO) { LoginExceptionEnum accountPasswordError = LoginExceptionEnum.ACCOUNT_PASSWORD_ERROR; //1,获取账号密码 String account = userLoginDTO.getAccount(); ​ //1.5如果账密不正确,那就返回错误 if((account.contains(" ")||userLoginDTO.getPassword().contains(" ")) ||(account.length()>20||account.length()<5)){ throw new MyWebException(accountPasswordError); } //2,查找账号,如果不存在直接返回错误值 UserEntity userEntity = lambdaQuery().eq(UserEntity::getAccount, account).one(); if(ObjectUtil.isEmpty(userEntity)){ throw new MyWebException(accountPasswordError); ​ } //3,查到到,用密码加盐 加密 String salt = userEntity.getSalt(); String md5 = DigestUtil.md5Hex(userLoginDTO.getPassword() + salt); ; //4,和数据库的密码比对 String password = userEntity.getPassword(); //5,比对失败,返回密码错误 if(!StrUtil.equals(md5,password)){ throw new MyWebException(accountPasswordError); } //6,成功,生成token,封装实体类一并返回 UserInfoDTO userInfoVO = new UserInfoDTO(); userInfoVO.setUserName(userEntity.getUserName()); userInfoVO.setAccount(userEntity.getAccount()); userInfoVO.setPhoneNumber(userEntity.getPhoneNumber()); userInfoVO.setId(userEntity.getId()); String token=null; try { UserInfoDTO userInfoDTO = BeanUtil.copyProperties(userEntity, UserInfoDTO.class); token = jwtUtil.generateToken(userInfoDTO); } catch (Exception e) { //7,token生成如果失败,直接抛异常,全局异常处理器处理后,返回给前端。 throw new RuntimeException(e); } //8,封装最后的login vo返回 UserLoginResponseDTO userLoginResponseDTO = new UserLoginResponseDTO(); userLoginResponseDTO.setInfoVO(userInfoVO); userLoginResponseDTO.setToken(token); ​ return userLoginResponseDTO; } }

3,dto、vo的含义和使用方式

dto叫做数据传输对象,主要有两个作用,一个是限制前端的输入,让输入框死于dto限制的字段如:CourierLoginDTO,另一个是充当安全的数据传输对象

​ @NotBlank(message = "账号不能为空") @Size(min = 3,max=20,message = "账号长度错误!") /** * 账号 */ private String account; @NotBlank(message = "密码不能为空") /** * 密码 */ private String password;

这是一个快递员dto类,限制登录字段只能是账密,不能输入其他如:balance字段和role字段,不然如果处理不当,用户可以随意修改余额(balance)和角色(role)字段!

但是在BFF+CoreService下,由于BFF服务侧重于处理前端服务,且为了防止BFF服务的请求DTO和CoreService的DTO数据传输对象混淆,所以把DTO改为了更加适合前段的VO。

如下是BFF的controller层

... public class AuthController { ... ​ @PostMapping("/login") //注意这里的请求参数,变成了VO,而不是dto! public ResponseEntity<UserBaseLoginVO> login(@RequestBody @Valid UserLoginRequestVO userLoginRequestVO){ UserBaseLoginVO userBaseLoginVO = authService.login(userLoginRequestVO); return ResponseEntity.success(userBaseLoginVO); } ​ }

因此dto的作用少了一个,不能限制前端,那就只能充当数据传输对象,用于屏蔽敏感字段如密码和盐值。

因此在CoreService服务中,基本上都是DTO的身影了,如下图,是快递员CoreService的后端Feign(具体不用看,主要看请求参数和方法返回值)

public interface CourierFeign { //这边都是DTO作为数据的传输对象了 CourierLoginResponseDTO login (CourierLoginRequestDTO courierLoginRequestDTO); ​ BasePageDTO<CourierDTO> getCourierList(BasePageRequestDTO basePageRequestDTO); ​ void create(CourierCreateDTO courierCreateDTO); ​ void updateCourier(CourierUpdateDTO courierUpdateDTO); ​ CourierDTO getById(Long courierId); ​ void deleteCourier(Long id); }

这样的架构下,VO和DTO大幅度分离,前端处理服务和核心业务界限清晰。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询