Eloquent 직렬화
번역일: 2026년 6월 20일
Eloquent 직렬화
소개
Laravel로 API를 개발할 때는 모델과 연관관계 데이터를 배열이나 JSON 형식으로 변환해야 할 경우가 많습니다. Eloquent는 이러한 변환을 간편하게 처리하는 메서드를 제공하며, 직렬화 결과에 어떤 속성을 포함할지도 세밀하게 제어할 수 있습니다.
NOTE
Eloquent 모델과 컬렉션의 JSON 직렬화를 더욱 체계적으로 관리하려면 Eloquent API 리소스 문서를 참고하세요.
모델과 컬렉션 직렬화
배열로 직렬화
모델과 로드된 연관관계를 배열로 변환하려면 toArray 메서드를 사용합니다. 이 메서드는 재귀적으로 동작하므로, 모든 속성과 연관관계(연관관계의 연관관계 포함)가 배열로 변환됩니다.
use App\Models\User;
$user = User::with('roles')->first();
return $user->toArray();연관관계를 제외하고 모델의 속성만 배열로 변환하고 싶다면 attributesToArray 메서드를 사용하세요.
$user = User::first();
return $user->attributesToArray();모델 컬렉션 전체를 배열로 변환할 때도 컬렉션 인스턴스에 toArray를 호출하면 됩니다.
$users = User::all();
return $users->toArray();JSON으로 직렬화
모델을 JSON으로 변환하려면 toJson 메서드를 사용합니다. toArray와 마찬가지로 재귀적으로 동작하여 모든 속성과 연관관계가 JSON으로 변환됩니다. PHP가 지원하는 JSON 인코딩 옵션도 함께 지정할 수 있습니다.
use App\Models\User;
$user = User::find(1);
return $user->toJson();
return $user->toJson(JSON_PRETTY_PRINT);모델이나 컬렉션을 문자열로 캐스팅하면 toJson 메서드가 자동으로 호출됩니다.
return (string) User::find(1);모델과 컬렉션은 문자열로 캐스팅될 때 자동으로 JSON으로 변환되므로, 라우트나 컨트롤러에서 Eloquent 객체를 그대로 반환할 수 있습니다. Laravel이 자동으로 JSON 직렬화를 처리합니다.
Route::get('/users', function () {
return User::all();
});연관관계 처리
Eloquent 모델을 JSON으로 변환할 때, 이미 로드된 연관관계는 JSON 객체의 속성으로 자동 포함됩니다. 연관관계 메서드는 카멜 케이스(camelCase)로 정의하지만, JSON에 포함될 때는 스네이크 케이스(snake_case)로 변환됩니다.
NOTE
예를 들어 roleGroups() 메서드로 정의된 연관관계는 JSON에서 role_groups 키로 출력됩니다.
JSON에서 속성 숨기기
비밀번호처럼 외부에 노출되어서는 안 되는 속성은 직렬화 결과에서 제외할 수 있습니다. 모델에 $hidden 프로퍼티를 선언하고, 숨기고 싶은 속성명을 배열로 지정하면 됩니다.
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
/**
* 직렬화 시 숨길 속성 목록
*
* @var array<string>
*/
protected $hidden = ['password'];
}NOTE
연관관계를 숨기려면 $hidden 배열에 연관관계 메서드 이름을 추가하면 됩니다.
반대로 $visible 프로퍼티를 사용하면 직렬화 결과에 포함할 속성을 명시적으로 허용 목록(allowlist) 방식으로 지정할 수 있습니다. $visible에 포함되지 않은 속성은 배열이나 JSON 변환 시 자동으로 제외됩니다.
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
/**
* 배열 변환 시 포함할 속성 목록
*
* @var array
*/
protected $visible = ['first_name', 'last_name'];
}속성 노출 여부 임시 변경
특정 모델 인스턴스에서 일시적으로 숨겨진 속성을 노출하고 싶다면 makeVisible 메서드를 사용하세요. 이 메서드는 모델 인스턴스를 반환하므로 메서드 체이닝이 가능합니다.
return $user->makeVisible('attribute')->toArray();반대로 평소에는 보이는 속성을 일시적으로 숨기려면 makeHidden 메서드를 사용하세요.
return $user->makeHidden('attribute')->toArray();보이는 속성 또는 숨겨진 속성 목록 전체를 임시로 교체하려면 setVisible과 setHidden 메서드를 각각 사용하세요.
return $user->setVisible(['id', 'name'])->toArray();
return $user->setHidden(['email', 'password', 'remember_token'])->toArray();JSON에 값 추가하기
데이터베이스 컬럼에 존재하지 않는 값을 배열이나 JSON 변환 결과에 포함하고 싶을 때가 있습니다. 이럴 때는 먼저 해당 값에 대한 접근자(accessor)를 정의합니다.
<?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',
);
}
}이 접근자를 항상 직렬화 결과에 포함시키려면 모델의 $appends 프로퍼티에 속성명을 추가합니다. 접근자 PHP 메서드는 카멜 케이스로 정의하지만, $appends에는 스네이크 케이스로 지정하는 점에 주의하세요.
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
/**
* 배열 변환 시 추가로 포함할 접근자 목록
*
* @var array
*/
protected $appends = ['is_admin'];
}$appends에 추가된 속성은 배열과 JSON 변환 결과 모두에 포함되며, 모델에 설정된 $visible 및 $hidden 규칙도 동일하게 적용됩니다.
런타임에 속성 추가하기
런타임에 특정 모델 인스턴스에만 추가 속성을 포함하고 싶다면 append 메서드를 사용하세요. setAppends 메서드를 사용하면 해당 인스턴스의 추가 속성 목록 전체를 교체할 수 있습니다.
return $user->append('is_admin')->toArray();
return $user->setAppends(['is_admin'])->toArray();날짜 직렬화
기본 날짜 형식 변경
serializeDate 메서드를 오버라이드하면 날짜 직렬화 시 사용할 기본 형식을 변경할 수 있습니다. 이 메서드는 배열이나 JSON으로 변환될 때의 표시 형식에만 영향을 미치며, 데이터베이스에 저장되는 형식에는 영향을 주지 않습니다.
/**
* 배열 / JSON 직렬화를 위한 날짜 형식을 지정합니다.
*/
protected function serializeDate(DateTimeInterface $date): string
{
return $date->format('Y-m-d');
}속성별 날짜 형식 변경
특정 날짜 속성의 직렬화 형식을 개별적으로 지정하려면 모델의 캐스트 선언에서 날짜 형식을 직접 명시하면 됩니다.
protected function casts(): array
{
return [
'birthday' => 'date:Y-m-d',
'joined_at' => 'datetime:Y-m-d H:00',
];
}