Certainly! Here’s a recommended approach to validating Spatie Laravel Settings using spatie/laravel-data in your API requests, including custom validation messages and TypeScript support.
1. Create a Data Class for Your Settings
Yes, your approach of creating a ColorSettingsData class is correct and aligns with best practices. This class will handle validation and transformation for your settings data.
namespace App\Data;
use App\Enums\Color;
use App\Enums\ColorShade;
use Illuminate\Validation\Rule;
use Spatie\LaravelData\Attributes\MergeValidationRules;
use Spatie\LaravelData\Data;
#[MergeValidationRules]
final class ColorSettingsData extends Data
{
public function __construct(
public bool $enabled,
public Color $name,
/** @var ColorShade[] $shades */
public array $shades,
) {}
public static function rules(): array
{
return [
'enabled' => ['required', 'boolean'],
'name' => ['required', Rule::enum(Color::class)],
'shades' => ['array'],
'shades.*' => ['distinct', Rule::enum(ColorShade::class)],
];
}
public static function messages(): array
{
return [
'name.enum' => 'The selected color is invalid.',
'shades.*.enum' => 'Invalid color shade selected.',
'shades.*.distinct' => 'Duplicate color shades are not allowed.',
];
}
}
2. Use the Data Class in Your Request
You can use the data class in your controller or form request. Here’s how you might use it in a controller:
use App\Data\ColorSettingsData;
use App\Settings\General\ColorSettings;
public function updateColorSettings(Request $request)
{
// Validate and transform the request data
$data = ColorSettingsData::from($request);
// Save to settings
app(ColorSettings::class)->fill([
'enabled' => $data->enabled,
'name' => $data->name,
'shades' => $data->shades,
])->save();
return response()->json(['message' => 'Settings updated!']);
}
Or, if you want to use a custom Form Request:
use Spatie\LaravelData\WithData;
class UpdateColorSettingsRequest extends FormRequest
{
use WithData;
public function rules(): array
{
return ColorSettingsData::rules();
}
public function messages(): array
{
return ColorSettingsData::messages();
}
public function dataClass(): string
{
return ColorSettingsData::class;
}
}
Then in your controller:
public function updateColorSettings(UpdateColorSettingsRequest $request)
{
$data = $request->getData();
app(ColorSettings::class)->fill([
'enabled' => $data->enabled,
'name' => $data->name,
'shades' => $data->shades,
])->save();
return response()->json(['message' => 'Settings updated!']);
}
3. TypeScript Support
If you want to generate TypeScript types from your Data class, you can use spatie/laravel-data-export:
php artisan data:export
This will generate TypeScript types for your data classes, which you can use in your frontend.
Summary:
- Create a
ColorSettingsDatadata class for validation and transformation. - Use it in your controller or a custom Form Request.
- Optionally, generate TypeScript types for frontend use.
This approach keeps your validation, transformation, and documentation (TypeScript) in sync and leverages the full power of both Spatie packages.