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