我正在使用JSON:API规范在Laravel中实现API。
在其中我有一个资源,让我们称之为Ponds,与另一个资源有多对多的关系,我们称之为Ducks。
根据JSON:API规范为了消除这种关系我应该使用DELETE / ponds / {id} / relationships / ducks端点,请求下面的主体:
{
"data": [
{ "type": "ducks", "id": "123" },
{ "type": "ducks", "id": "987" }
]
}
这由PondRemoveDucksRequest处理,如下所示:
<?php
...
class PondRemoveDucksRequest extends FormRequest
{
public function authorize()
{
return $this->allDucksAreRemovableByUser();
}
public function rules()
{
return [
"data.*.type" => "required|in:ducks",
"data.*.id" => "required|string|min:1"
];
}
protected function allDucksAreRemovableByUser(): bool
{
// Here goes the somewhat complex logic determining if the user is authorized
// to remove each and every relationship passed in the data array.
}
}
问题是,如果我发送一个身体,如:
{
"data": [
{ "type": "ducks", "id": "123" },
{ "type": "ducks" }
]
}
,我得到500,因为首先触发授权检查,它依赖于数组的每个项目中存在的ID。理想情况下,我想从规则验证中获得标准消息的422错误。
我看到的快速修复是在allDucksAreRemovableByUser()方法中添加id存在检查,但这看起来有点hacky。
有没有更好的方法首先检查验证规则,然后才进入授权部分?
提前致谢!
这是一种与您尝试的方法略有不同的方法,但它可以为您实现预期的结果。
如果您尝试验证给定的duck id是否属于用户,可以在规则本身中完成,如下所示:
"data.*.id" => "exists:ducks,id,user_id,".Auth::user()->id
此规则询问ducks表中是否存在与id匹配的记录,以及user_id是当前登录的user_id的位置。
如果你将它链接到你现有的规则(required | string | min:1),使用'bail',那么它将不会运行查询,除非它首先传递了其他三个规则:
"data.*.id" => "bail|required|string|min:1|exists:ducks,id,user_id,".Auth::user()->id