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

# Eloquent 시리얼라이제이션

> Eloquent 모델을 JSON·배열로 변환하는 방법, 속성의 표시·비표시 제어, 추가 속성 설정, 날짜 포맷 커스터마이징을 설명합니다.

## 소개

Laravel에서 API를 구축할 때 모델과 그 관계를 배열이나 JSON으로 변환해야 하는 경우가 자주 있습니다.
Eloquent에는 이러한 변환을 수행하기 위한 편리한 메서드와, 시리얼라이즈된 모델 표현에 어떤 속성을 포함할지를 제어하는 기능이 포함되어 있습니다.

<Info>
  Eloquent 모델과 컬렉션의 보다 견고한 JSON 시리얼라이제이션 방법에 대해서는 [Eloquent API 리소스](./eloquent-resources) 문서를 참조해 주세요.
</Info>

## 모델과 배열

### 배열로의 시리얼라이제이션

모델과 로드된 [관계](./eloquent-relationships)를 배열로 변환하려면 `toArray` 메서드를 사용합니다.
이 메서드는 재귀적으로 동작하며 모든 속성과 모든 관계(관계의 관계까지 포함)가 배열로 변환됩니다.

```php theme={null}
use App\Models\User;

$user = User::with('roles')->first();

return $user->toArray();
```

`attributesToArray` 메서드를 사용하면 관계를 제외한 모델의 속성만 배열로 변환할 수 있습니다.

```php theme={null}
$user = User::first();

return $user->attributesToArray();
```

모델의 컬렉션 전체를 배열로 변환하려면 컬렉션 인스턴스의 `toArray` 메서드를 호출합니다.

```php theme={null}
$users = User::all();

return $users->toArray();
```

### JSON으로의 시리얼라이제이션

모델을 JSON으로 변환하려면 `toJson` 메서드를 사용합니다.
`toArray`와 마찬가지로 `toJson` 메서드도 재귀적이므로 모든 속성과 관계가 JSON으로 변환됩니다.
[PHP가 지원하는 JSON 인코딩 옵션](https://secure.php.net/manual/en/function.json-encode.php)을 지정할 수도 있습니다.

```php theme={null}
use App\Models\User;

$user = User::find(1);

return $user->toJson();

return $user->toJson(JSON_PRETTY_PRINT);
```

모델이나 컬렉션을 문자열로 캐스팅할 수도 있으며, 그 경우 모델이나 컬렉션의 `toJson` 메서드가 자동으로 호출됩니다.

```php theme={null}
return (string) User::find(1);
```

모델과 컬렉션은 문자열로 캐스팅되면 JSON으로 변환되므로, 애플리케이션의 라우트나 컨트롤러에서 Eloquent 객체를 직접 반환할 수 있습니다.
Laravel은 라우트나 컨트롤러에서 반환되는 Eloquent 모델과 컬렉션을 자동으로 JSON으로 시리얼라이즈합니다.

```php theme={null}
Route::get('/users', function () {
    return User::all();
});
```

#### 관계

Eloquent 모델이 JSON으로 변환될 때, 로드된 관계는 JSON 객체의 속성으로 자동으로 포함됩니다.
또한 Eloquent의 관계 메서드는 "카멜케이스" 메서드명으로 정의되지만, 관계의 JSON 속성은 "스네이크케이스"가 됩니다.

## 속성 표시 제어

### 속성 비표시

모델의 배열이나 JSON 표현에 포함되는 비밀번호 같은 속성을 제한하고 싶은 경우가 있습니다.
이를 위해서는 모델에 `Hidden` 애트리뷰트를 사용합니다.
`Hidden` 애트리뷰트에 나열된 속성은 모델의 시리얼라이즈된 표현에 포함되지 않습니다.

```php theme={null}
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Attributes\Hidden;
use Illuminate\Database\Eloquent\Model;

#[Hidden(['password'])]
class User extends Model
{
    // ...
}
```

<Info>
  관계를 비표시로 하려면 Eloquent 모델의 Hidden 애트리뷰트에 관계의 메서드명을 추가합니다.
</Info>

### 속성 공개

`Visible` 애트리뷰트를 사용해 모델의 배열 및 JSON 표현에 포함되어야 할 속성의 "허용 목록"을 정의할 수도 있습니다.
`Visible` 애트리뷰트에 존재하지 않는 모든 속성은 모델이 배열이나 JSON으로 변환될 때 비표시가 됩니다.

```php theme={null}
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Attributes\Visible;
use Illuminate\Database\Eloquent\Model;

#[Visible(['first_name', 'last_name'])]
class User extends Model
{
    // ...
}
```

### 속성의 일시적 표시·비표시

일반적으로 비표시로 되어 있는 속성을 특정 모델 인스턴스에서 표시하려면 `makeVisible` 또는 `mergeVisible` 메서드를 사용합니다.
`makeVisible` 메서드는 모델 인스턴스를 반환합니다.

```php theme={null}
return $user->makeVisible('attribute')->toArray();

return $user->mergeVisible(['name', 'email'])->toArray();
```

반대로 일반적으로 표시되는 속성을 비표시로 하려면 `makeHidden` 또는 `mergeHidden` 메서드를 사용합니다.

```php theme={null}
return $user->makeHidden('attribute')->toArray();

return $user->mergeHidden(['name', 'email'])->toArray();
```

표시나 비표시 속성을 모두 일시적으로 오버라이드하려면 `setVisible` 및 `setHidden` 메서드를 각각 사용합니다.

```php theme={null}
return $user->setVisible(['id', 'name'])->toArray();

return $user->setHidden(['email', 'password', 'remember_token'])->toArray();
```

## 추가 속성

모델을 배열이나 JSON으로 변환할 때, 데이터베이스에 대응하는 컬럼을 가지지 않는 속성을 추가하고 싶은 경우가 있습니다.
이를 위해서는 먼저 값의 [액세서](./eloquent-mutators)를 정의합니다.

```php theme={null}
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * 사용자가 관리자인지 판정한다.
     */
    protected function isAdmin(): Attribute
    {
        return new Attribute(
            get: fn () => 'yes',
        );
    }
}
```

액세서를 모델의 배열 및 JSON 표현에 항상 추가하려면 모델에 `Appends` 애트리뷰트를 사용합니다.
액세서의 PHP 메서드는 "카멜케이스"로 정의되지만, 속성명은 일반적으로 "스네이크케이스"로 시리얼라이즈 표현을 사용합니다.

```php theme={null}
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Attributes\Appends;
use Illuminate\Database\Eloquent\Model;

#[Appends(['is_admin'])]
class User extends Model
{
    // ...
}
```

속성이 `appends` 리스트에 추가되면 모델의 배열과 JSON 표현 양쪽에 포함됩니다.
`appends` 배열의 속성도 모델에 설정된 `visible`과 `hidden` 설정을 존중합니다.

### 실행 시 추가

실행 시 `append` 또는 `mergeAppends` 메서드를 사용해 모델 인스턴스에 추가 속성을 추가하도록 지시할 수 있습니다.
또한 `setAppends` 메서드를 사용해 특정 모델 인스턴스의 추가 프로퍼티 배열 전체를 오버라이드할 수 있습니다.

```php theme={null}
return $user->append('is_admin')->toArray();

return $user->mergeAppends(['is_admin', 'status'])->toArray();

return $user->setAppends(['is_admin'])->toArray();
```

추가된 모든 프로퍼티를 모델에서 제거하려면 `withoutAppends` 메서드를 사용합니다.

```php theme={null}
return $user->withoutAppends()->toArray();
```

## 날짜 시리얼라이제이션

### 기본 날짜 포맷 커스터마이징

`serializeDate` 메서드를 오버라이드함으로써 기본 시리얼라이제이션 포맷을 커스터마이징할 수 있습니다.
이 메서드는 데이터베이스로의 저장을 위한 날짜 포맷에는 영향을 주지 않습니다.

```php theme={null}
/**
 * 배열·JSON 시리얼라이제이션을 위해 날짜를 준비한다.
 */
protected function serializeDate(DateTimeInterface $date): string
{
    return $date->format('Y-m-d');
}
```

### 속성별 날짜 포맷 커스터마이징

모델의 [캐스트 선언](./eloquent-mutators#attribute-casting)에서 날짜 포맷을 지정함으로써 개별 Eloquent 날짜 속성의 시리얼라이제이션 포맷을 커스터마이징할 수 있습니다.

```php theme={null}
protected function casts(): array
{
    return [
        'birthday' => 'date:Y-m-d',
        'joined_at' => 'datetime:Y-m-d H:00',
    ];
}
```


## Related topics

- [Laravel 12에서 13으로의 업그레이드 가이드](/ko/blog/upgrade-12-to-13.md)
- [Laravel 13 신기능 정리](/ko/blog/laravel-13-new-features.md)
- [로컬라이제이션](/ko/localization.md)
- [Redis](/ko/redis.md)
- [Eloquent 컬렉션](/ko/eloquent-collections.md)
