본문 바로가기

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();

보이는 속성 또는 숨겨진 속성 목록 전체를 임시로 교체하려면 setVisiblesetHidden 메서드를 각각 사용하세요.

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', ]; }

이 문서는 Laravel 공식 문서(MIT)를 한국 개발자를 위해 번역·재구성한 것입니다.

번역일: 2026년 6월 20일