求证,控制器和service、service和service间参数传递和验证

  1. 路由模型绑定时,将 id 转换为对应模型,控制器接收模型实例,service层参数接收应该怎么设计?是接收模型实例还是接收 id 参数好些?
    // service中
    public function update($noteId, $validated)
    /// or 
    public function update(Note $note, $validated)
  2. 如果接收模型实例,要保证实例中存在需要的属性,只能在方法中手动验证吗?比如要确定 deleted_at是否存在在模型中👇,
    $model->offsetExists('deleted_at')
  3. service 层的方法,存在互相调用,参数验证应该怎么做?目前是在 controller 中使用的 form request,然后传递验证后的数据给 service👇,这样 A service 调用当前 service 的方法,需要在 A 中验证参数还是在当前 service中验证参数,通过什么验证?
    //controller
    public function foobar(StoreFoobarRequest $request)
    {
     $this->service->store($request->safe());
    }

如果能通过引入别的层来解决问题,也是极好的,(☆▽☆)

《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
最佳答案

如果你认为外部传入对象是不可信的,那就只能传递 ID。

如果你的业务中很容易遇到这种,有模型要传递的情况,那么你再创建一个 updateForModel 方法,用来接收模型,update 方法用来接收 ID, update 方法内部调用 updateForModel,即实现重载。

还可以使用 getter、setter 的方式,把这些参数声明成类属性来调用。

比如声明 $note 属性类型为 Note|int 即同时接受模型和 int 参数类型,在 setter 或者 getter 方法里面去处理(使最终拿到模型,毕竟你需要使用)。

传递给 Service 的参数,应该始终是最终可用的,即 Service 里面不做参数验证,而是在方法签名上就定义类型的形式来限定。

4周前 评论
讨论数量: 4

如果你认为外部传入对象是不可信的,那就只能传递 ID。

如果你的业务中很容易遇到这种,有模型要传递的情况,那么你再创建一个 updateForModel 方法,用来接收模型,update 方法用来接收 ID, update 方法内部调用 updateForModel,即实现重载。

还可以使用 getter、setter 的方式,把这些参数声明成类属性来调用。

比如声明 $note 属性类型为 Note|int 即同时接受模型和 int 参数类型,在 setter 或者 getter 方法里面去处理(使最终拿到模型,毕竟你需要使用)。

传递给 Service 的参数,应该始终是最终可用的,即 Service 里面不做参数验证,而是在方法签名上就定义类型的形式来限定。

4周前 评论

我的习惯 很少丢对象 一般都是丢id 方便解耦

3周前 评论
Bear_zheng

1.传递id会浪费之前绑定的模型,会遇到在服务层内需要这个模型怎么再获取的问题,不管从持久化还是缓存获取都是比较浪费时间的。如果要传递id,可以做一下进程内缓存

2、3是类似的,服务层方法需要使用合法的参数,参数有问题需要在方法外做校验,无效的话不需要调用。

3周前 评论
gema

我的习惯是传model, 一般跟客户端对接的只有controller 而其他部分都是内部调用, 甚至controller调用service的方法也是内部调用. 那么数据就应该是可信的. 不需要再做额外的校验. 至于service中想校验字段存不存在, 基于前面的话 传递过来的model是可信的 所以不用校验. 或者 如果真不确定 可以 $model->refresh() 从数据库重新获取一遍

3周前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!