Spatie Laravel/数据未格式化错误

问题描述 投票:0回答:1

我正在做一个项目,在这个项目中我使用 Spatie 的 laravel-data 包 (https://spatie.be/docs/laravel-data/v2/introduction) 来管理数据传输对象 (DTO)。我有一些 DTO 目前工作正常,直到我遇到这个我面临 2 个问题:

1 到目前为止,我已经能够在我的控制器中使用 DTO 作为参数,并且请求已正确转换为 DTO,例如:

public function store(ProductData $data) : ProductsResource
    {
        $product = UpsertProductAction::execute($data);
        return new ProductsResource($product->load('category'));
    }

现在我有一个客户实体的自定义路由。路线定义如下:

Route::post('customers/individuals', [ CustomersController::class, 'addIndividual' ]);

我控制器中的

addIndividual
方法是:

public function addIndividual(IndividualData $data)
    {
        echo "here";
        print_r($data);
        dd("watup");
    }

但是当我从我的 REST 客户端访问路由时,我什么也得不到。调试时它似乎没有击中控制器。我收到 200 OK 响应和 Laravel 的主页,仅此而已。

但是如果我修改我的方法是:

public function addIndividual(Request $request)
{
    
       $data = IndividualData::from($request->all());
       dd($data);
}

现在我看到

dd
被击中了。 这是怎么回事?

这是我的数据类:

<?php

namespace Domain\Customer\DataTransferObjects;

use Illuminate\Validation\Rule;
use Spatie\LaravelData\Data;

class IndividualData extends Data
{
    public function __construct(
        public readonly ?string $id,
        public readonly string $identification,
        public readonly string $identification_type,
        public readonly string $first_name,
        public readonly ?string $middle_name,
        public readonly string $last_name,
        public readonly ?string $second_last_name,
        public readonly ?string $primary_phone_number,
        public readonly ?string $primary_phone_number_type,
    ) {}

    public static function rules() : array
    {
        return [
            'identification' => [
                'required',
                'string',
            ],
            'identification_type' => [
                'required',
                'string',
            ],
            'first_name' => [
                'required',
                'string',
            ],
            'middle_name' => [
                'string',
                'nullable',
                'sometimes'
            ],
            'last_name' => [
                'required',
                'string',
            ],
            'second_last_name' => [
                'string',
                'nullable',
                'sometimes'
            ],
            'primary_phone_number' => [
                'string',
                'nullable',
                'sometimes'
            ],
            'primary_phone_number_type' => [
                'string',
                'nullable',
                'sometimes'
            ],
        ];
    }

}

2 第二个问题与第一个问题相关。所以用以前的方法,比如

public function store(ProductData $data) : ProductsResource
    {
        $product = UpsertProductAction::execute($data);
        return new ProductsResource($product->load('category'));
    }

如果有一些数据在

ProductData
中按要求声明但未通过,那么我会得到一个很好的错误,如:

{
    "message": "The barcode field is required. (and 1 more error)",
    "errors": {
        "barcode": [
            "The barcode field is required."
        ],
        "name": [
            "The name has already been taken."
        ]
    }
}

但是现在,如果我简单地使用请求并将其注入数据对象:

$data = IndividualData::from($request->all());
并且请求中缺少必需的数据然后我收到 500 错误消息,例如:

Could not create `Domain\Customer\DataTransferObjects\IndividualData`: the constructor requires 9 parameters, 8 given.Parameters given: id, identification_type, first_name, middle_name, last_name, second_last_name, primary_phone_number, primary_phone_number_type.

如果我在

try/catch
声明中注入创建 DTO 的请求:

try {
            $data = IndividualData::from($request->all());
            $dto = $data;
            $customer = UpsertCustomerAction::execute($data);

        } catch (\Exception $exception) {
            return $exception;
        }

然后我得到:

参数计数错误: 域\客户\DataTransferObjects\IndividualData::__construct(): 参数 #2 ($identification) 未传入 /Users/hansgruber/Desktop/webdev/projects/dundermifflin-be/src/Domain/Customer/DataTransferObjects/IndividualData.php:10 堆栈跟踪:#0 /Users/hansgruber/Desktop/webdev/projects/dundermifflin-be/vendor/spatie/laravel-data/src/Resolvers/DataFromArrayResolver.php(57): Domain\Customer\DataTransferObjects\IndividualData->__construct(NULL, NULL,'CC','Inigo',NULL,'Montoya','Arias','6464654635','cel')#1 /Users/hansgruber/Desktop/webdev/projects/dundermifflin-be/vendor/spatie/laravel-data/src/Resolvers/DataFromArrayResolver.php(38): Spatie\LaravelData\Resolvers\DataFromArrayResolver->createData(对象(Spatie\LaravelData\Support\DataClass), 对象(照明\支持\集合))#2 /Users/hansgruber/Desktop/webdev/projects/dundermifflin-be/vendor/laravel/framework/src/Illuminate/Collections/Traits/EnumeratesValues.php(731): Spatie\LaravelData\Resolvers\DataFromArrayResolver->Spatie\LaravelData\Resolvers{闭包}(对象(照明\支持\集合)) #3 /Users/hansgruber/Desktop/webdev/projects/dundermifflin-be/vendor/spatie/laravel-data/src/Resolvers/DataFromArrayResolver.php(38): Illuminate\Support\Collection->pipe(Object(Closure))#4 /Users/hansgruber/Desktop/webdev/projects/dundermifflin-be/vendor/spatie/laravel-data/src/Resolvers/DataFromSomethingResolver.php(45): Spatie\LaravelData\Resolvers\DataFromArrayResolver->execute('Domain\Customer...', 对象(照明\支持\集合))#5

为什么我不再收到格式正确的错误?

谢谢。

laravel laravel-9 dto laravel-data
1个回答
0
投票

花了几个小时四处寻找这个问题!事实证明,我的 REST 客户端的请求中没有设置以下标头:

Accept: application/json

最糟糕的是,我所有的其他请求都有它,但其中大部分是具有标题的请求的修改副本,我手动创建了失败的请求,原因是我忘记了它

© www.soinside.com 2019 - 2024. All rights reserved.