Apigility 确实支持特定于动词的验证器。验证器仅在 POST、PUT 和 PATCH 上应用或需要。DELETE 和 GET 不带任何正文,这是 Apigility 支持验证的请求的唯一部分。
此外,您可能不太可能希望 API 的用户提供 id。这是相当罕见的。正如您在 POST 中指出的那样,可能会生成 id。这也意味着将为 PUT 和 PATCH 提供 id,但它应该是 URL 的一部分。
例如:
PUT /address/4
PATCH /address/5
在您的路线中,您应该有类似 /address[/:id] 的内容。根据是否提供此 id 将确定在您的资源类中调用什么方法。没有 id (PUT /address) 的 PUT 会调用 replaceList,而有 id 的 PUT 会调用 update。带有 id 的 PATCH 调用 patch 方法。没有 id 的 PATCH 是没有意义的。
如果要约束 URL 中的值,可以向路由的选项添加约束部分,如下所示:
'router' => array(
'routes' => array(
'your-api.rest.address' => array(
'type' => 'Segment',
'options' => array(
'route' => '/address[/:address_id]',
'defaults' => array(
'controller' => 'YourApi\V1\Rest\Address\Controller',
),
'constraints' => array(
'address_id' => '[0-9]+',
),
),
),
),
),
)
约束的键应该与路由中 id 变量的名称相匹配。该值将是一个与 id 可能的合法值匹配的正则表达式。您不为此包含正则表达式分隔符。它会发出类似/address/banana
返回 404 的请求,并且该请求不会进入您的资源代码。
有了这个,我建议从你的字段列表中删除 id 字段。您可能能够对 POST、PUT 和 PATCH 使用相同的验证器集。了解如何根据动词应用验证器也很重要。
在所有动词中,如果您配置了过滤器,则这些过滤器将在验证之前应用于提供的字段。这意味着,例如,如果您有一个 \Zend\Filter\Digits 过滤器,那么所有非数字将在验证之前被删除。如果您的验证器类似于 \Zend\Validator\Digits,那么只要该字段包含至少一位数字,它就会有效。
基于动词应用验证器的方式略有不同。在 POST 和 PUT(在 URL 中带有 id)中,您可以包含验证器中未指定的额外字段。在 PATCH 中,如果您发送任何未在验证器中指定的字段,则会出现错误。
对于没有 id 的 PUT(路由到 replaceList),预期的主体将是一个对象数组。
验证器的最后一个警告是,如果您将过滤器应用于任何字段并且验证通过,则传递给任何方法的 $data 中的值将是应用过滤之前的值。回到前面的示例,其中包含 Digits 过滤器和 Digits 验证器的字段,如果您发送类似{'my_field': '1234banana56'}
的内容,它将通过验证,但 $data 中的值不会是 123456,而是 1234banana56。如果要获取过滤后的值,则需要执行以下操作:
$filteredData = $this->getInputFilter()->getValues();
这将为您返回一个过滤和验证字段值的数组。验证器中未指定的任何字段都不会在此数组中返回。已经讨论过使这种行为可配置,以便 $data 接收过滤后的数据值,但在撰写本文时,它就是这样工作的。
如果您确实发现需要基于不同动词的不同验证器,答案在此处的文档中:https ://apigility.org/documentation/content-validation/advanced
希望这一切都有帮助。