Php Symfony Api Rest哪个验证程序进程

Php Symfony Api Rest哪个验证程序进程,php,json,symfony,validation,Php,Json,Symfony,Validation,我的问题涉及json有效负载验证的各种过程。 我收到: -对模型进行反序列化,调用验证器服务并验证水合对象。 -使用FormType(即使没有表单…只有json提要)并在注入$datas后验证表单生成器 你喜欢哪一个? 你有更好的解决办法吗?比如一个中间件(处理所有输入/输出有效负载的唯一捆绑ou应用程序-请求/响应) 谢谢我使用本机侦听器/工具验证/反序列化FOSRestBundle提供的 利用捆绑包,您可以进行本机表单验证。。。或者自动反序列化和验证模型,以及作为控制器参数注入的验证错误列表

我的问题涉及json有效负载验证的各种过程。 我收到: -对模型进行反序列化,调用验证器服务并验证水合对象。 -使用FormType(即使没有表单…只有json提要)并在注入$datas后验证表单生成器

你喜欢哪一个? 你有更好的解决办法吗?比如一个中间件(处理所有输入/输出有效负载的唯一捆绑ou应用程序-请求/响应)


谢谢

我使用本机侦听器/工具验证/反序列化
FOSRestBundle
提供的

利用捆绑包,您可以进行本机表单验证。。。或者自动反序列化和验证模型,以及作为控制器参数注入的验证错误列表

# app/config/config.yml 

# You need SensioFrameworkExtraBundle for body converters to work
sensio_framework_extra:
  request: { converters: true }

fos_rest:
  zone:
    - path: '^/api/(.*)+$'
  # [..]
  body_listener:
    enabled: true
    default_format: json
    decoders:
      json: fos_rest.decoder.jsontoform

  # automatically injects query parameters into controller Actions
  # see @FOSRest\QueryParam in the example below
  param_fetcher_listener: force

  # https://symfony.com/doc/master/bundles/FOSRestBundle/request_body_converter_listener.html
  body_converter:
    enabled: true
    validate: true
    validation_errors_argument: validationErrors
body转换器可以为您自动反序列化和验证模型(无需使用任何表单或手动步骤)。例如:

/**
 * @ParamConverter(
 *   "post", 
 *   converter = "fos_rest.request_body",
 *   options = {
 *     "validator" = {
 *       "groups" = {
 *         "validation-group-one",
 *         "validation-group-two",
 *       }
 *     },
 *     "deserializationContext" = {
 *       "groups" = { 
 *         "serializer-group-one",
 *         "serializer-group-two"
 *       }, 
 *       "version"="1.0"
 *     }
 *   }
 * )
 */
public function putPostAction(Post $post, ConstraintViolationListInterface $validationErrors)
{ 
    if (!empty($validationErrors)) {
        // return some 4xx reponse
    }
    // Do something with your deserialized and valid Post model
该捆绑包还可以将表单(以及表单错误)序列化为JSON

i、 e.具有无效字段的表单将呈现为:

{
    "code": 400,
    "message": "Validation Failed",
    "errors": {
        "errors": [
            "This is a global form error."
        ],
        "children": {
            "oldPassword": {
                "errors": [
                    "The old password is not correct."
                ]
            },
            "newPassword": [],
            "submit": []
        }
    }
}
FOSRestBundle
提供了一个请求主体侦听器,该侦听器自动将
内容类型:application/json
解码为
内容:application/x-www-form-urlencoded
对象中的
请求
,这样您就可以使用
handleRequest
将请求绑定到表单,就像使用普通HTML一样表格

快速提示:如果您只是想异步验证数据。。。在执行任何业务逻辑之前,您可以使用查询参数(
?validate=true
)发送请求,并使用HTTP 200(确定)/202(接受)返回早期响应

以下示例显示了接受表单请求的端点:

{
    "oldPassword": "xxxxxxx",
    "newPassword": "yyyyyyy"
}
相应的控制器动作:

/**
 * @FOSRest\Route(
 *   "/profile/change-password",
 *   name="api_put_password",
 *   methods={
 *     Request::METHOD_PUT
 *   }
 * )
 *
 * @FOSRest\QueryParam(
 *   name="validate",
 *   allowBlank=false,
 *   default="false",
 *   strict=true,
 *   nullable=true,
 *   requirements="^(true|false)$"
 * )
 */
public function putPasswordAction(Request $request, string $validate = 'false')
{
    $validate = filter_var($validate, FILTER_VALIDATE_BOOLEAN);

    $form = $this->formFactory->createNamed(null, ChangePasswordType::class, null, [
        'action' => $this->router->generateUrl('api_put_password'),
        'method' => $request->getMethod(),
    ]);

    $form->handleRequest($request);

    if (!$form->isValid()) {
        $view = new View();
        $view->setStatusCode(Response::HTTP_BAD_REQUEST);
        $view->setData($form);

        return $view;
    }

    if ($validate) {
        $view = new View();
        $responseCode = Response::HTTP_ACCEPTED;
        $view->setStatusCode($responseCode);
        $view->setData([
            'code'  => $responseCode,
            'message' => 'Data is valid.',
            'data' => null
        ]);

        return $view;
    }

    $user = $this->securityContext->getToken()->getUser();
    /** @var PasswordChangeRequest $passwordChangeRequest */
    $passwordChangeRequest = $form->getData();
    $user->setPassword($this->passwordEncoder->encodePassword($user, $passwordChangeRequest->getNewPassword()));
    $this->userManager->persist($user);

    $view = new View();
    $view->setStatusCode(Response::HTTP_OK);
    $view->setData([
        'code'  => Response::HTTP_OK,
        'message' => 'Password changed successfully.',
        'data' => $user
    ]);

    $context = new Context();
    $context->setGroups([
        'profile'
    ]);
    $view->setContext($context);

    return $view;
}

对我来说,最好的选择是实体水合的形式,所以你有动态的验证过程调用你的水合实体。错误处理已经存在,etcI正在寻找这种解决方案nifr,它是完美的!谢谢。我对paramconverter@nifr有点问题,添加到控制器操作的params改变了url格式,例如“Post$Post”现在包含在url中。你知道我只能处理http_row_post_数据和post方法吗,也就是说,只处理$request->getContent(),我的json负载在哪里?这似乎是两个不同的问题,对吗?通过显式提供@Route或添加@NoRoute并将该路由的配置直接放入
routing.yml
,可以防止控制器参数显示在url中。操作参数通常仅添加到具有隐式路由/URL命名的URL。你用这个吗?我不明白第二部分。是否要访问控制器操作中的原始JSON负载?问题是,如果url中没有数据,paramconverter将无法工作…因此我无法使用paramConverte:)。