Laravel 8批量接口如何复用FormRequest验证单条数据
复用Laravel FormRequest实现批量数据验证
方法一:手动实例化CarRequest验证单条数据
在CarService的bulk方法中,你可以手动创建CarRequest实例,将单条车辆数据注入后触发验证逻辑,和单条请求的验证行为完全一致,验证失败会自动抛出标准的ValidationException。
修改后的bulk方法代码:
public function bulk($request) { foreach ($request->cars AS $carData ) { // 实例化单条验证的CarRequest $carRequest = new CarRequest(); // 将当前循环的车辆数据转为数组,合并到请求输入中 $carRequest->merge((array)$carData); // 执行验证逻辑,失败则抛出异常 $carRequest->validateResolved(); $car = Car::where('plate','=',$carData->plate)->first(); if ($car){ $this->update($carRequest, $car); // 传入验证后的请求实例 } else { $this->store($carRequest, Car::class); } } }
关键说明:
merge((array)$carData):把对象类型的$carData转为数组后,覆盖请求默认的输入数据,让CarRequest使用当前单条车辆数据做验证validateResolved():FormRequest内部的核心验证方法,会自动执行规则校验、权限检查(authorize方法),完全复用原有逻辑
方法二:创建批量请求类复用CarRequest规则
如果希望在控制器层面先完成整个批量请求的合法性校验,再进入服务层处理,可以新建一个批量请求类,直接复用CarRequest的规则:
class CarBulkRequest extends BaseRequest { public function authorize() { $this->setModel(Car::class); return $this->isAuthorized(); } public function rules() { // 获取CarRequest定义的单条数据规则 $singleCarRules = (new CarRequest())->rules(); return [ 'cars' => 'required|array', 'cars.*' => 'required|array', // 为数组中的每一项应用单条规则 'cars.*.model' => $singleCarRules['model'], 'cars.*.year' => $singleCarRules['year'], 'cars.*.plate' => $singleCarRules['plate'], ]; } public function messages() { // 复用CarRequest的错误消息,或自定义批量场景的提示 $singleMessages = (new CarRequest())->messages(); $bulkMessages = []; // 为批量数据添加索引标识,方便用户定位错误位置 foreach ($singleMessages as $field => $msg) { $bulkMessages["cars.*.$field"] = "第N条车辆数据的{$field}:{$msg}"; } return $bulkMessages; } }
然后修改控制器的bulk方法,直接注入批量请求类:
public function bulk(CarBulkRequest $request) { $this->carService->bulk($request); }
这种方式会先校验整个请求的格式和所有车辆数据,全部合法后再执行业务逻辑,适合需要整体校验的场景。
注意事项
- 如果
CarRequest的authorize方法依赖当前请求的上下文(比如用户权限),两种方法都能正常继承会话、用户等信息 - 方法一中如果需要收集所有错误再统一返回,可以手动捕获
ValidationException,将错误信息存入数组,最后抛出包含所有错误的异常
内容的提问来源于stack exchange,提问作者Diego G
相关产品推荐
相关产品推荐

