Eloquent: 직렬화

1 개요[ | ]

Eloquent: Serialization
엘로퀀트: 직렬화

2 소개[ | ]

Laravel로 API를 구축할 때 모델과 관계를 배열이나 JSON으로 변환해야 하는 경우가 많습니다. Eloquent에는 이러한 변환을 위한 편리한 메소드가 포함되어 있으며, 모델의 직렬화된 표현에 포함되는 속성을 제어할 수도 있습니다.

Eloquent 모델 및 컬렉션 JSON 직렬화를 더욱 강력하게 처리하는 방법을 알아보려면, Eloquent API 리소스에 대한 문서를 확인하세요.

3 모델과 콜렉션 직렬화[ | ]

3.1 배열로 직렬화[ | ]

모델과 로드된 관계를 배열로 변환하려면 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();

3.2 JSON으로 직렬화[ | ]

모델을 JSON으로 변환하려면 toJson 메소드를 사용해야 합니다. toArray 메소드와 마찬가지로 toJson 메소드도 재귀적으로 동작하여 모든 속성과 관계가 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 객체를 직접 반환할 수 있습니다. 라라벨은 라우트나 컨트롤러에서 반환된 Eloquent 모델과 컬렉션을 자동으로 JSON으로 직렬화합니다:

Route::get('users', function () {
    return User::all();
});
관계

Eloquent 모델이 JSON으로 변환될 때, 로드된 관계도 JSON 객체의 속성으로 자동으로 포함됩니다. 또한, Eloquent 관계 메소드는 "camel case" 메서드 이름으로 정의되지만, 관계의 JSON 속성은 "snake case"로 표시됩니다.

4 JSON에서 속성 숨기기[ | ]

때로는 패스워드와 같은 속성을 모델의 배열 또는 JSON 표현에 포함하지 않도록 제한하고 싶을 때가 있습니다. 이를 위해 모델에 $hidden 속성을 추가하세요. $hidden 속성 배열에 나열된 속성은 모델의 직렬화된 표현에 포함되지 않습니다:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * 배열에 포함되지 않아야 하는 속성들.
     *
     * @var array
     */
    protected $hidden = ['password'];
}

관계(relationships)를 숨기려면 관계 메소드 이름을 Eloquent 모델의 $hidden 속성에 추가하세요.

반대로, visible 속성을 사용하여 모델의 배열 및 JSON 표현에 포함해야 하는 속성의 "허용 목록"을 정의할 수 있습니다. $visible 배열에 없는 모든 속성은 모델이 배열 또는 JSON으로 변환될 때 숨겨집니다:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * 배열에 포함되어야 하는 속성들.
     *
     * @var array
     */
    protected $visible = ['first_name', 'last_name'];
}
속성 가시성 임시 변경

일반적으로 숨겨진 속성을 특정 모델 인스턴스에서 보이도록 하고 싶다면 makeVisible 메소드를 사용할 수 있습니다. 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();

5 JSON에 값 덧붙이기[ | ]

때때로 모델을 배열이나 JSON으로 변환할 때 데이터베이스에 해당하는 열이 없는 속성을 추가하고 싶을 수 있습니다. 이를 위해 먼저 값에 대한 접근자를 정의해야 합니다:

<?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 메소드는 "camel case"로 정의되었지만 속성 이름은 "snake case" 직렬화 표현을 사용하여 참조된다는 점에 유의하세요:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * 모델의 배열 형식에 추가할 접근자들.
     *
     * @var array
     */
    protected $appends = ['is_admin'];
}

속성이 appends 목록에 추가되면 모델의 배열 및 JSON 표현에 포함됩니다. appends 배열의 속성은 모델에 설정된 visiblehidden 설정도 따릅니다.

런타임에 추가하기

런타임에, 추가 속성을 모델 인스턴스에 추가하려면 append 메소드를 사용할 수 있습니다. 또는 setAppends 메소드를 사용하여 특정 모델 인스턴스에 대한 전체 추가 속성 배열을 재정의할 수 있습니다:

return $user->append('is_admin')->toArray();

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

6 날짜 직렬화[ | ]

기본 날짜 형식 커스터마이징

기본 직렬화 형식을 커스터마이징하려면 serializeDate 메소드를 재정의하면 됩니다. 이 메소드는 날짜가 데이터베이스에 저장되는 형식에는 영향을 미치지 않습니다:

/**
 * 배열 / JSON 직렬화를 위한 날짜 준비.
 */
protected function serializeDate(DateTimeInterface $date): string
{
    return $date->format('Y-m-d');
}
속성별 날짜 형식 커스터마이징

Eloquent 날짜 속성의 직렬화 형식을 개별적으로 커스터마이징하려면 모델의 cast 선언에서 날짜 형식을 지정할 수 있습니다:

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

7 같이 보기[ | ]

문서 댓글 ({{ doc_comments.length }})
{{ comment.name }} {{ comment.created | snstime }}