Validator for HTTP requests.isListOf, isMapOf), reducing runtime errors in complex data structures like DTOs or API payloads.webmozart/assert with niche validations (e.g., Bank, Coordinates, IBAN/BIC), critical for industries like finance, logistics, or geospatial applications.composer require.app()->make('assert') or Assert::isListOf()).webmozart/assert (10M+ downloads), with minimal surface area for failure. MIT license eliminates legal concerns.IBAN, BIC) may have undocumented limitations (e.g., locale-specific formats). Requires custom testing.isListOf/isMapOf calls could lead to exponential validation time for complex structures. Mitigate with early exits or batch validation.atournayre/assert in App\Services\OrderService but Laravel Validator in App\Http\Requests\StoreOrderRequest.ValidationException for consistent API responses, or use custom exceptions?try {
Assert::isListOf($request->items, Product::class);
} catch (InvalidArgumentException $e) {
throw ValidationException::withMessages(['items' => [$e->getMessage()]]);
}
IBAN validation for non-EU countries)?Coordinates validation fails for antipodal points)?symfony/validator: More feature-rich but heavier.spatie/laravel-validation-rules: Laravel-specific, but lacks domain assertions.| Criteria | atournayre/assert |
symfony/validator |
Custom Traits |
|---|---|---|---|
| Domain Assertions | ✅ (IBAN, Coordinates) | ❌ | ✅ (but manual) |
| Performance | ⚠️ (Exceptions) | ✅ (Batch validation) | ✅ (Optimized) |
| Laravel Integration | ✅ (Easy) | ⚠️ (Complex) | ✅ (Native) |
| Maintenance | ❌ (External) | ✅ (Active) | ❌ (Internal) |
OrderService::calculateTotal()).assert($dto->metadata, isMapOf(Metadata::class))).assert($event->payload, isListOf(OrderItem::class))).assert($args['iban'], isBankAccount())).FormRequest instead).UserProfileService) to replace manual validation with assertions.composer.json:
composer require atournayre/assert
// Before
if (!is_array($data['items']) || !isset($data['items'][0]['id'])) {
throw new \InvalidArgumentException("Invalid items format.");
}
// After
Assert::isListOf($data['items'], Item::class, "Items must be an array of Item objects.");
// app/Providers/AppServiceProvider.php
use Atournayre\Assert\Assert;
public function register()
{
$this->app->singleton('assert', function () {
return new Assert();
});
}
/**
* @throws \InvalidArgumentException if $items is not a list of Product.
*/
public function processItems(array $items): void
{
Assert::isListOf($items, Product::class);
// ...
}
// app/Exceptions/Handler.php
public function register()
{
$this->renderable(function (\InvalidArgumentException $e, $request) {
return response()->json([
'message' => $e->getMessage(),
'errors' => ['validation' => [$e->getMessage()]],
], 422);
});
}
// app/Http/Middleware/ValidateAssertions.php
public function handle($request, Closure $next)
{
try {
$next($request);
} catch (\InvalidArgumentException $e) {
throw ValidationException::withMessages([
'error' => [$e->getMessage()]
]);
}
}
webmozart/assert compatibility).webmozart/assert is a low-level dependency with no known conflicts.use Atournayre\Assert\Assert
How can I help you explore Laravel packages today?