> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# InteractsWithData 트레이트

> Illuminate\Support\Traits\InteractsWithData의 설계와, 패키지 개발에서 자체 클래스에 데이터 접근 API를 구현하는 방법을 해설합니다.

## InteractsWithData 트레이트란

`Illuminate\Support\Traits\InteractsWithData`는, "배열 유사 입력 데이터에 대한 공통 API"를 모은 트레이트입니다.

이 트레이트 자체는 `all()`과 `data()`의 2개만을 추상 메서드로 요구하고, 실 데이터의 취득 로직은 각 클래스 측에 위임합니다. 대신, 다음과 같은 고빈도 메서드를 한꺼번에 제공합니다.

* 존재 판정: `has()`, `hasAny()`, `exists()`, `missing()`
* 공백 판정: `filled()`, `isNotFilled()`, `anyFilled()`
* 조건 실행: `whenHas()`, `whenFilled()`, `whenMissing()`
* 추출: `only()`, `except()`
* 타입 변환: `string()`, `boolean()`, `integer()`, `float()`, `date()`, `enum()`, `collect()`

## Request 계열 메서드와의 관계

`request()` 헬퍼로 취득하는 `Illuminate\Http\Request`는, `Concerns\InteractsWithInput`을 통해 `InteractsWithData`를 받아들입니다.

그 때문에, 다음과 같은 일상적인 입력 접근은 트레이트 경유로 제공되고 있습니다.

```php theme={null}
$search = request()->input('search');

if (request()->has('search')) {
    $filters = request()->only(['search', 'status']);
}

$payload = request()->except(['_token']);
```

`Request::get()`은 `Request` 클래스 본체에 있는 Symfony 호환 메서드입니다. Laravel 13의 소스 코드상에서도 `@deprecated use ->input() instead`로 명기되어 있으며, 권장은 `input()`입니다.

```php theme={null}
$legacy = request()->get('search');  // 互換目的のメソッド（推奨は input()）
```

## Laravel 코어에서의 주요 구현 예

### 직접 `InteractsWithData`를 use하는 클래스

| 클래스                                           | 용도                               |
| --------------------------------------------- | -------------------------------- |
| `Illuminate\Http\Concerns\InteractsWithInput` | `Request`의 입력 접근 API             |
| `Illuminate\Support\ValidatedInput`           | `validated()` / `safe()`의 반환값 래퍼 |
| `Illuminate\Support\Fluent`                   | 설정값이나 임의 속성의 유창한 조작              |
| `Illuminate\Support\UriQueryString`           | `Uri`의 쿼리 문자열 조작                 |
| `Illuminate\View\ComponentAttributeBag`       | Blade 컴포넌트 속성의 조작                |

### 유사 책무를 가진 관련 구현

* `Illuminate\Session\Store`는 `has()`, `get()`, `only()`, `except()` 등 비슷한 API를 독자적으로 구현하고 있습니다
* `Illuminate\Validation\Concerns\ValidatesAttributes`는 검증 판정 로직을 제공하며, 입력 접근 API 자체는 `InteractsWithData`와는 별개의 책무로 설계되어 있습니다

## 트레이트와 주요 클래스의 관계

```mermaid theme={null}
flowchart TD
    IWD["InteractsWithData<br>공통 데이터 접근 API"] --> IWI["InteractsWithInput<br>Request 대상 Concern 트레이트"]
    IWI --> REQ["Request<br>input()/has()/only()/except()"]
    IWD --> VIN["ValidatedInput<br>safe()/validated()"]
    IWD --> FLU["Fluent"]
    IWD --> UQS["UriQueryString"]
    IWD --> CAB["ComponentAttributeBag"]
    REQ -.유사 API 패턴.-> SES["Session Store<br>has()/get()/only()/except() 를 독자 구현"]
    REQ -.관련 영역(직접 의존이 아님).-> VAL["ValidatesAttributes<br>검증 판정 로직"]
```

## 패키지 개발에서 자체 클래스에 결합하기

`InteractsWithData`는, 패키지 내에서 "입력 배열을 보관하며 Laravel풍의 취득 API를 제공하고 싶은" 클래스에 적합합니다.

<Steps>
  <Step title="데이터 컨테이너 클래스를 만들기">
    ```php theme={null}
    namespace Vendor\Package\Support;

    use Illuminate\Support\Arr;
    use Illuminate\Support\Traits\InteractsWithData;

    class OptionBag
    {
        use InteractsWithData;

        /**
         * @param  array<string, mixed>  $items
         */
        public function __construct(
            protected array $items = [],
        ) {}

        public function all($keys = null): array
        {
            if (! $keys) {
                return $this->items;
            }

            $result = [];

            $keyList = is_array($keys) ? $keys : [$keys];

            foreach ($keyList as $key) {
                Arr::set($result, $key, Arr::get($this->items, $key));
            }

            return $result;
        }

        protected function data($key = null, $default = null): mixed
        {
            return data_get($this->items, $key, $default);
        }
    }
    ```
  </Step>

  <Step title="타입 지정 액세서로 안전하게 읽기">
    ```php theme={null}
    $options = new OptionBag([
        'feature.enabled' => 'true',
        'retry.max' => '5',
        'channels' => ['mail', 'slack'],
    ]);

    $enabled = $options->boolean('feature.enabled'); // true
    $retryMax = $options->integer('retry.max');      // 5
    $channels = $options->collect('channels');       // Collection
    $public = $options->except(['secret']);          // secret を除外
    ```
  </Step>
</Steps>

## 실전 유스케이스

* 외부 API 클라이언트의 옵션 백
* 웹훅 페이로드의 정규화 레이어
* 패키지의 설정 오버라이드 해결 클래스

`all()`과 `data()`만 구현하면, 입력 접근 API를 매번 직접 만들지 않아도 되므로 유지보수 비용을 낮출 수 있습니다.

## 관련 페이지

* [Macroable 트레이트](/ko/advanced/macroable)
* [Conditionable 트레이트](/ko/advanced/conditionable)
* [tap() 헬퍼와 Tappable 트레이트](/ko/advanced/tap)


## Related topics

- [InteractsWithTime 트레이트](/ko/advanced/interacts-with-time.md)
- [Fluent 클래스](/ko/advanced/fluent.md)
- [Macroable 트레이트](/ko/advanced/macroable.md)
- [Dumpable 트레이트](/ko/advanced/dumpable.md)
- [Conditionable 트레이트](/ko/advanced/conditionable.md)
