在Symfony 4中验证Rest Api

时间:2019-02-17 21:20:24

标签: rest api validation symfony4

我将为我的项目编写REST API。我正在使用symfony4。我看到了几个示例,但没有一个适合我。

  1. 具有Form对象的验证。它对我不起作用,因为它是API,没有表单。我不想仅仅为了支持此功能而编写虚拟类。
  2. 在此页面https://symfony.com/doc/current/validation.html上,他们建议了4种方式:注释,yml,xml,php。此解决方案不适合我,因为此验证与实体API有关-模式更广泛:它具有限制,偏移量,过滤器和其他不属于实体的字段。

所以,我想我需要编写验证器,该验证器具有所有可能字段的约束数组。我只是不知道什么是最好的呈现方式。你见过类似的东西吗?

P.S。在写这篇文章之前,我使用了stackoverflow搜索。我没有找到有用的答案。

2 个答案:

答案 0 :(得分:1)

看看您的示例(example.com/api/categories?limit=20&offset=300&filter=something),我想您的操作将如下所示:

public function getCategories(?int $limit, ?int $offset, ?string $filter)
{
    //...
}

集合验证

您可以将约束定义为数组(然后将其抽象为自己的类),并将其作为第二个参数传递给验证器。

$constraint = new Assert\Collection([
    'limit' => [
        new Assert\Range(['min' => 0, 'max' => 999]),
        new Assert\DivisibleBy(0.5)
    ],
    'offset' => new Assert\Range(['min' => 0, 'max' => 999]),
    'filter' => new Assert\Regex("/^\w+/")
]);

$validationResult = $this->validator->validate(
    ['limit' => $limit, 'offset' => $offset, 'filter' => $filter],
    $constraint
);

文档link

一个一个地验证

对于要验证的每个参数,将约束作为第二个参数传递给验证器。

$offsetValidationResult = $this->validator->validate(
    $offset,
    new Assert\Range(['min' => 0, 'max' => 999])
);
//...

文档link

对象验证

创建一个包含3个字段的类。

class FilterParameters
{
    public function __construct($limit, $offset, $filter)
    {
        $this->limit = $limit;
        $this->offset = $offset;
        $this->filter = $filter;
    }

    // No getters/setters for brevity
    /**
     * @Assert\DivisibleBy(0.25)
     */
    public $limit;
    /**
     * @Assert\Range(min = 0, max = 999)
     */
    public $offset;
    /**
     * @Assert\Regex("/^\w+/")
     */
    public $filter;
}

实例化并验证它。

$validationResult = $this->validator->validate(
    new FilterParameters($limit, $offset, $filter)
);

文档link

答案 1 :(得分:0)

我认为照常使用表格是非常干净和不错的。 https://codereviewvideos.com/course/beginners-guide-back-end-json-api-front-end-2018/video/validating-json-data-symfony

我选择此api,因为它是我测试中最快的。 您不必购买该课程(但如果您喜欢此代码,则可以这样做),只需按照本系列中的“ raw symfony 4”文章(您也不需要behat部分)

“限制”,“偏移”和“过滤器”功能属于您的存储库。与您将ID传递到存储库的方式相同

/**
 * Class AlbumController
 * @package App\Controller
 */
class AlbumController extends AbstractController
{
    // ....

    /**
     * @Route(
     *     path         = "/api/album/{id}",
     *     name         = "get_album",
     *     methods      = {"GET"},
     *     requirements = {"id"="\d+"}
     * )
     * @param int $id
     *
     * @return JsonResponse
     */
    public function get($id)
    {
        return new JsonResponse($this->findAlbumById($id), JsonResponse::HTTP_OK);
    }  

    /**
     * @param $id
     *
     * @return Album|null
     * @throws NotFoundHttpException
     */
    private function findAlbumById($id)
    {
        $album = $this->albumRepository->find($id);

        if ($album === null) {
            throw new NotFoundHttpException();
        }

        return $album;
    }