---
title: "Definitions & validation — Attributes for Laravel | Roundly"
description: "Register known attributes with a type and Laravel validation rules, seed them from config, and opt into strict mode."
url: https://roundly-consulting.com/open-source/docs/attributes-for-laravel/definitions
language: en
---

[All packages](https://roundly-consulting.com/open-source.md)

[Attributes for Laravel](https://roundly-consulting.com/open-source/docs/attributes-for-laravel.md)

# Definitions & validation

Register known attributes with a type and validation rules. Registered attributes are always validated on write and stored in their defined type:

```php
use RoundlyConsulting\Attributes\Facades\Attributes;
use RoundlyConsulting\Attributes\DataTransferObjects\AttributeDefinitionData;
use RoundlyConsulting\Attributes\Enums\AttributeType;

Attributes::define(new AttributeDefinitionData(
    name: 'rating',
    type: AttributeType::Integer,
    rules: ['min:1', 'max:5'],
));

Attributes::for($product)->set('rating', 9); // throws InvalidAttributeValueException
```

## Registering definitions

Register definitions in a service provider’s boot() method, or seed them through the definitions config key (see Configuration):

```php
namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use Illuminate\Validation\Rule;
use RoundlyConsulting\Attributes\DataTransferObjects\AttributeDefinitionData;
use RoundlyConsulting\Attributes\Enums\AttributeType;
use RoundlyConsulting\Attributes\Facades\Attributes;

class AppServiceProvider extends ServiceProvider
{
    public function boot(): void
    {
        Attributes::defineMany(
            new AttributeDefinitionData('rating', AttributeType::Integer, rules: ['min:1', 'max:5']),
            new AttributeDefinitionData('size', AttributeType::String_, rules: [Rule::in(['S', 'M', 'L'])]),
            new AttributeDefinitionData('launched_at', AttributeType::DateTime),
            new AttributeDefinitionData('tags', AttributeType::Array_, rules: ['max:10']),
        );
    }
}
```

AttributeDefinitionData takes name, type, rules, default, required, unique and encrypted — everything after type is optional. The AttributeType cases that clash with PHP keywords carry a trailing underscore: String\_, Float\_ and Array\_.

## How validation works

- The type’s own rule comes first — string, integer, numeric (float), boolean, array or date (datetime) — followed by your rules.
- Rules may be strings or rule objects, exactly as in a Laravel validator; the attribute name is used as the field label in messages.
- null values are never validated.
- Undefined names are not validated at all — unless strict mode rejects them.

## Strict mode

Set ATTRIBUTES\_STRICT=true to reject any attribute name that is not registered — writing a value or its meta throws UnknownAttributeException. A name counts as registered when it has a global definition (config or Attributes::define()) or one in the owner model’s own schema:

```php
// .env: ATTRIBUTES_STRICT=true

Attributes::define(new AttributeDefinitionData('color', AttributeType::String_));

Attributes::for($product)->set('color', 'white');   // registered: fine
Attributes::for($product)->set('nickname', 'Blue'); // throws UnknownAttributeException
```

## The definitions API

The facade’s definition methods delegate to RoundlyConsulting\\Attributes\\Registry\\AttributeRegistry, the container singleton that stores definitions:

| Method | Purpose |
| --- | --- |
| `define($definition) / defineMany(...$definitions)` | Register (or replace) definitions. |
| `has($name) / get($name) / all()` | Inspect the global definitions. |
| `forget($name) / flush()` | Unregister one definition, or all of them. |
| `resolveFor(?$owner, $name)` | The definition that applies to an owner — its model schema first, then global. |
| `definitionsFor($owner)` | Global definitions overlaid by the owner’s model schema. |
| `default($name, ?$owner = null)` | A definition’s default value. |
| `requiredNames()` | Names of the required global definitions. |
| `validate($name, $value) / validateFor(?$owner, $name, $value)` | Validate a value; throws InvalidAttributeValueException. |
| `assertUnique($owner, $name, $value)` | Uniqueness check; throws DuplicateAttributeValueException. |
| `isStrict() / assertKnown($name, ?$owner = null)` | Strict-mode state and check — given the owner, its model schema counts too; throws UnknownAttributeException. |

```php
use RoundlyConsulting\Attributes\Facades\Attributes;

Attributes::has('rating');                   // bool
Attributes::get('rating')?->rules;           // ['min:1', 'max:5']
Attributes::all();                           // array<string, AttributeDefinitionData>
Attributes::definitionsFor($product);        // global + the model's own schema
Attributes::resolveFor($product, 'rating');  // the definition that applies to this owner
Attributes::default('retries', $product);    // a definition's default value
Attributes::requiredNames();                 // required names among global definitions
Attributes::validate('rating', 4);           // throws InvalidAttributeValueException if invalid
Attributes::forget('rating');                // unregister one
Attributes::flush();                         // unregister all
```

## Show your open-source love

This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.

[More ways to support, including crypto](https://roundly-consulting.com/support-us.md)

By donating, you agree to our [donation terms](https://roundly-consulting.com/donation-terms.md).

[Support our open source work (opens in a new tab)](https://donate.stripe.com/dRmeVe8FX5PF1Qd9pXcEw00) [Join us on Patreon (opens in a new tab)](https://www.patreon.com/cw/roundly)

## Want this built into your product?

We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.

[Get a quote in 48 hours](https://roundly-consulting.com/contact.md) [Browse all packages](https://roundly-consulting.com/open-source/docs/attributes-for-laravel.md)
