Eloquent 직렬화
업데이트됨번역일: 2026년 6월 20일
이 페이지는 원문이 업데이트되어 번역이 갱신되었습니다.
- 원문 수정
- 2026년 6월 20일
- 번역 갱신
- 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)로 변환됩니다.
JSON에서 특정 속성 숨기기
비밀번호처럼 외부에 노출되어서는 안 되는 속성은 배열이나 JSON 변환 결과에서 제외할 수 있습니다. 모델에 Hidden 속성(PHP 어트리뷰트)을 추가하면, 지정한 필드가 직렬화 결과에서 자동으로 제외됩니다.
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Attributes\Hidden;
use Illuminate\Database\Eloquent\Model;
#[Hidden(['password'])]
class User extends Model
{
// ...
}NOTE
연관 관계를 숨기려면, Hidden 어트리뷰트에 해당 연관 관계 메서드명을 추가하면 됩니다.
반대로, 직렬화 결과에 포함할 속성만 명시적으로 허용하는 "허용 목록" 방식을 사용하려면 Visible 어트리뷰트를 사용하세요. Visible에 지정되지 않은 속성은 배열이나 JSON 변환 시 자동으로 숨겨집니다.
<?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 메서드를 사용하세요. 두 메서드 모두 모델 인스턴스를 반환합니다.
return $user->makeVisible('attribute')->toArray();
return $user->mergeVisible(['name', 'email'])->toArray();반대로, 평소에는 노출되는 속성을 특정 인스턴스에서만 임시로 숨기려면 makeHidden 또는 mergeHidden 메서드를 사용하세요.
return $user->makeHidden('attribute')->toArray();
return $user->mergeHidden(['name', 'email'])->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',
);
}
}접근자를 항상 배열 및 JSON 변환 결과에 포함시키려면, 모델에 Appends 어트리뷰트를 추가하세요. 접근자 메서드는 카멜 케이스로 정의되지만, 속성 이름은 스네이크 케이스로 지정하는 것에 주의하세요.
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Attributes\Appends;
use Illuminate\Database\Eloquent\Model;
#[Appends(['is_admin'])]
class User extends Model
{
// ...
}Appends에 추가된 속성은 배열 및 JSON 변환 결과 모두에 포함되며, 모델에 설정된 visible/hidden 규칙도 그대로 적용됩니다.
런타임에 속성 추가하기
코드 실행 중에 특정 모델 인스턴스에 추가 속성을 덧붙이려면 append 또는 mergeAppends 메서드를 사용하세요. 추가 속성 목록 전체를 교체하려면 setAppends 메서드를 사용하면 됩니다.
return $user->append('is_admin')->toArray();
return $user->mergeAppends(['is_admin', 'status'])->toArray();
return $user->setAppends(['is_admin'])->toArray();추가된 속성을 모두 제거하고 싶다면 withoutAppends 메서드를 사용하세요.
return $user->withoutAppends()->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',
];
}