我想使用 MapRequestPayload 将 JSON 请求解析为嵌套的 DTO。目标是验证 DTO 中的数据。
JSON 示例:
{
"meta": {
"locale": "ger",
"validateOnly": false
},
"content": {
"firstName": "firstName",
"lastName": "lastName",
"displayMode": "system",
"favoriteMandates": [
{
"mandateId": "{{mandateId}}",
"position": 0
}
]
}
}
“元”始终包含相同的数据集,而内容因端点而异。
更新:我已经与一所大学讨论了这个问题,他希望我研究第二种方法。所以我重新表述了下面的所有内容。
final class UpdateUserSettingsController {
#[Route(
path: '/api/v1/user/settings',
methods: [HttpUpdate::REQUEST]
)]
public function execute(
#[MapRequestPayload(acceptFormat: 'json')]
JsonRequest $request
): JsonResponse
{
$settingsDTO = new UpdateUserSettingsDto(...$request->content);
//... do something
}
}
use Symfony\Component\Validator\Constraints as Assert;
final class JsonRequest
{
public function __construct(
#[Assert\Valid]
public MetaWithAttributes $meta,
#[Assert\Type('array')]
public array $content,
)
{}
}
use Symfony\Component\Validator\Constraints as Assert;
use CustomConstrains;
final readonly class UpdateUserSettingsDto
{
public Name $name;
public FavoriteMandatesCollection $favoriteMandates;
public function __construct(
string $firstName,
string $lastName,
#[Assert\IsArray] array $favoriteMandates,
#[CustomConstrains\IsEnumValue(DisplayModeEnum::class)] string $displayMode,
) {
$this->name = Name::fromStrings($firstName, $lastName);
$this->favoriteMandates = FavoriteMandatesCollection::fromInputArray($favoriteMandates);
$this->displayMode = DisplayModeEnum::fromString($displayMode);
}
}
我现在的问题是我需要以某种方式告诉 Symfony 需要检查属性(因此以某种方式使用验证器?)。
如果有人有不同/更好的方法来解决这个问题,而不需要每个端点的请求类和 dto 类,我很乐意尝试一下。
您需要向数组添加注释,以便映射器了解要使用哪个类进行对象映射并可以应用验证器。
#[Assert\Type('countable')]
#[Assert\All(new Assert\Type(type: Contact::class))]
#[Assert\Valid]
/**
* @var Contact[]
*/
public array $contacts = [],
我的有效负载示例:
"contacts": [
{
"title": "",
"text": "",
"href": "",
"icon": "",
"sortOrder": 0
},
{
"title": "string",
"text": "string",
"href": "string",
"icon": "string",
"sortOrder": 0
}
],
输出:
{
"errors": {
"contacts[0].title": "This value should not be blank.",
"contacts[0].text": "This value should not be blank."
}
}