【问题标题】:Validation for Rest Api in Symfony 4Symfony 4 中的 Rest Api 验证
【发布时间】:2019-02-17 21:20:23
【问题描述】:

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

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

所以,我想我需要编写一个验证器,它对所有可能的字段都有一组约束。我只是不知道呈现这个的最佳方式是什么。你见过类似的东西吗?

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

【问题讨论】:

  • 你能提供一个 symfony 验证器不适合的例子吗?您的数据看起来如何?
  • 例如我触发了 Rest API 并想要获取类别列表。所以我发送获取请求example.com/api/categories?limit=20&offset=300&filter=something。 “限制”、“偏移”和“过滤器”不属于实体“类别”,但我必须验证它们。

标签: rest api validation symfony4


【解决方案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

【讨论】:

    【解决方案2】:

    我认为像往常一样使用表单是非常干净和漂亮的。 https://codereviewvideos.com/course/beginners-guide-back-end-json-api-front-end-2018/video/validating-json-data-symfony

    我选择这个 api,因为它是我测试中最快的。 您不必购买课程(但如果您喜欢代码,可以购买),只需按照本系列中的“原始 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;
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-02
      • 2018-02-05
      • 2019-01-12
      • 1970-01-01
      • 1970-01-01
      • 2020-01-14
      相关资源
      最近更新 更多