1

在我目前正在使用 Apigility 开发的 Zend Framework 2 应用程序中,有一个资源address,它提供以下访问点:

GET /address
    id <-- required

PATCH /address
    id <-- required
    street
    zip
    city
    type

好的。现在我开始实现另一个用于插入项目的方法:

POST /address
    street
    zip
    city
    type

由于在 POST 方法的上下文中id不需要它,因此它不是必需的。问题是,在 Apigility 中没有上下文相关的字段/字段集(还没有?)。所以为了实现 POST 方法,我必须为所有方法创建id字段not-required。但后来我必须使它们成为 GET 和 PATCH 所必需的manually(但不知道如何)。

  1. 是否可以在 Apigility 中定义上下文相关的字段/字段集?(也许我根本没有找到这个选项。)

  2. 如果不是:有哪些方法可以处理这个问题?

4

1 回答 1

2

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

希望这一切都有帮助。

于 2015-05-14T05:10:53.343 回答