Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Assert Laravel Package

webmozart/assert

Webmozart Assert provides efficient PHP assertions for method input and output, throwing Webmozart\Assert\InvalidArgumentException on failure. It reduces validation boilerplate and supports clear custom error messages with consistent placeholders.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require webmozart/assert
    

    No additional configuration is required—just autoload the Webmozart\Assert\Assert facade or class.

  2. First Use Case: Validate constructor arguments in a Laravel model or service:

    use Webmozart\Assert\Assert;
    
    class UserService {
        public function __construct(private int $maxRetries) {
            Assert::integer($maxRetries, 'Max retries must be an integer. Got: %s');
            Assert::greaterThan($maxRetries, 0, 'Max retries must be positive. Got: %s');
        }
    }
    
  3. Where to Look First:

    • Assertion List: README’s table of assertions (bookmark this).
    • Placeholder Syntax: %s (value), %2$s (additional context like min/max). Example:
      Assert::minLength($name, 3, 'Name must be at least %2$s characters. Got: %s');
      

Implementation Patterns

1. Constructor Validation

Workflow:

  • Validate all constructor dependencies upfront.
  • Use Assert::isInstanceOf() for type-hinted parameters (redundant but explicit):
    public function __construct(private UserRepository $users) {
        Assert::isInstanceOf($users, UserRepository::class);
    }
    

2. Request Validation (Replacing Form Requests)

Pattern: Replace Laravel’s FormRequest with lightweight assertions in controllers:

public function store(Request $request) {
    Assert::string($request->name, 'Name is required.');
    Assert::email($request->email);
    Assert::minLength($request->password, 8, 'Password must be 8+ chars.');
    // ...
}

3. Domain-Specific Validation

Example: UUID Handling

public function findByUuid(string $uuid) {
    Assert::uuid($uuid, 'Invalid UUID format.');
    // Proceed with DB query...
}

4. Custom Error Messages

Template:

Assert::string($value, 'Expected %s, got: %s', ['string', gettype($value)]);

Use Case: Override default messages for API responses (e.g., JSON-friendly errors).

5. Integration with Laravel’s Validator

Pattern: Use assertions in Validator rules for reusable logic:

Validator::extend('custom_rule', function ($attribute, $value, $parameters) {
    Assert::string($value);
    Assert::minLength($value, 5);
    return true;
});

6. Testing

Pattern: Validate test inputs/outputs:

public function testCreateUser() {
    $user = new User('invalid@email');
    $this->expectException(InvalidArgumentException::class);
    $this->expectExceptionMessage('Invalid email format.');
}

Gotchas and Tips

Pitfalls

  1. Type Juggling:

    • Assert::integer() rejects floats (use Assert::integerish() for loose checks).
    • Assert::numeric() allows strings like "123" (be explicit if needed).
  2. Resource Assertions:

    • Assert::resource() requires PHP’s is_resource()—avoid in modern Laravel (use SplFileObject or StreamInterface instead).
  3. Performance:

    • Heavy assertions (e.g., regex(), uuid()) in loops can slow down code. Cache results if reused.
  4. Custom Classes:

    • Assert::isInstanceOf() checks exact class names. For abstract classes, use Assert::isAOf():
      Assert::isAOf($value, AbstractModel::class);
      
  5. Placeholder Order:

    • Mistake: %1$s won’t work—use %s (value) and %2$s (context).
    • Fix: Check the source code for placeholder details.

Debugging Tips

  1. Silent Failures:

    • Wrap assertions in try-catch for graceful degradation:
      try {
          Assert::email($email);
      } catch (InvalidArgumentException $e) {
          Log::error($e->getMessage());
          return response()->json(['error' => 'Invalid email'], 400);
      }
      
  2. Dynamic Messages:

    • Use sprintf-like placeholders for context:
      Assert::greaterThan($age, 18, 'Age must be >18. Got: %s (min: 18)');
      
  3. Testing Assertions:

    • Mock Assert in unit tests to verify validation paths:
      $this->expectException(InvalidArgumentException::class);
      $this->expectExceptionMessage('Invalid format.');
      

Extension Points

  1. Custom Assertions:

    • Extend the Assert class or create a trait:
      trait CustomAssertions {
          public static function validSlug(string $slug) {
              Assert::string($slug);
              Assert::regex($slug, '/^[a-z0-9\-]+$/i');
          }
      }
      
  2. Laravel Service Provider:

    • Bind a custom assertion facade:
      // app/Providers/AppServiceProvider.php
      public function register() {
          $this->app->bind('assert', function () {
              return new CustomAssertions();
          });
      }
      
  3. Integration with Laravel Pipes:

    • Create a pipe for reusable validation:
      namespace App\Pipes;
      
      use Webmozart\Assert\Assert;
      
      class ValidateUserPipe {
          public function handle($request, Closure $next) {
              Assert::string($request->name);
              return $next($request);
          }
      }
      

Config Quirks

  • No Configuration: Unlike Laravel packages, webmozart/assert has no config file. All behavior is code-driven.
  • Exception Handling: Always catch Webmozart\Assert\InvalidArgumentException for consistent error handling.

Pro Tips

  1. Combine Assertions:

    Assert::string($value)
        ->minLength(3)
        ->maxLength(255);
    

    (Note: Requires a fluent interface wrapper—see this gist for examples.)

  2. Laravel Blade: Use assertions in Blade templates (carefully—avoid performance hits):

    @php
        use Webmozart\Assert\Assert;
        Assert::string($user->name);
    @endphp
    
  3. API Responses: Normalize error messages for APIs:

    try {
        Assert::email($email);
    } catch (InvalidArgumentException $e) {
        return response()->json(['errors' => ['email' => $e->getMessage()]]);
    }
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource