laraveldtolaravel-data

How to properly use Spatie\LaravelData for retrieveing data?


I was introduced to Spatie\LaravelData when I was searching for how to implement DTOs in Laravel. Using Data classes for insert/update for a single model is pretty straightforward. I tend to keep my updates atomic in this way.

However I have a problem for using LaravelData to retrieve objects and send to front end, specially with nested models.

I have this example I have Post and Category models:

class Post extends Model
{
    use HasFactory;

    protected $fillable = [
        'title',
        'category_id'
    ];

    public function category(): BelongsTo
    {
        return $this->belongsTo(Category::class);
    }

}

class Category extends Model
{
    use HasFactory;

    protected $fillable = [
        'category',
        'description'
    ];
}

I have these Data classes:

class PostData extends Data
{
    public function __construct(
        public string $title,
        public string $category_id,
    ) {
    }
}

class CategoryData extends Data
{
    public function __construct(
        public string $category,
        public string $description
    ) {
    }
}

I want to be able to send a STO object with Post and its Category, also would love to be able to have a collection of Posts and their Categories for index page.

I tried using this approach as described in their documentation, but first it gives an error and second I'm not sure how to return that from index() or view() methods in controller:

class PostData extends Data
{
    public function __construct(
        public string $title,
        public string $category_id,
        #[DataCollectionOf(CategoryData::class)]
        public DataCollection $category,
    ) {
    }
}

Anyone ever used Spatie\LaravelData for returning DTOs to from end?


Solution

  • You are trying to use a DataCollection when you should be using nesting. This is because your post has a BelongsTo relationship with the category model.

    class PostData extends Data
    {
        public function __construct(
            public string $title,
            public string $category_id,
            public CategoryData $category,
        ) {
        }
    }