박유성의 라라벨 블로그

라라벨 옵저버 소개 ( Introducing Laravel Observers ) 본문

번역

라라벨 옵저버 소개 ( Introducing Laravel Observers )

Matt.park 2020. 8. 4. 10:41
작성자(Elisha Ukpong)에게 해당 포스팅의 번역을 동의받고 작성된 내용입니다.

원문 : https://medium.com/dev-genius/introducing-laravel-observers-8f0198c6c9c

 

Introducing Laravel Observers.

Laravel framework comes with a lot of awesome features, one that stands out for me is the model observers.

medium.com

 

 

라라벨프레임워크 에는 멋진 기능들이 많이 포함돼 있습니다. 저에게 있어 가장 뛰어난 기능은 observers 입니다. 문서에 따르면

주어진 모델을 여러 이벤트들을 수신하고자 하는 경우, 옵저버를 사용하여 모든 리스너를 하나의 클래스로 구성할 수 있습니다. 옵저버 클래스는 수신하고자 하는 Eloquent 이벤트에 대항하는 메소드 이름을 가집니다. 각각의 이 메소드들은 인자로 모델을 전달 받습니다. make:observer 아티즌 명령어는 새로운 옵저버 클래스를 생성하는 가장 쉬운 방법입니다.
(참고 : laravel.kr/docs/7.x/eloquent#%EC%98%B5%EC%A0%80%EB%B2%84%20%EA%B0%9D%EC%B2%B4%20%EC%A0%95%EC%9D%98%ED%95%98%EA%B8%B0)

옵저버는 모델 이벤트 전후에 실행해야 할 clean-up codes로 내 컨트롤러를 정리하는 데 도움이 되며 모델 이벤트의 lifecycle에 연결하고 적절하다고 생각되는 로직을 실행할 수 있는 방법을 제공합니다.

모델 이벤트는 모델의 CRUD와 아래의 이벤트 항목들을 관찰할 수 있습니다:

  • Retrieved

  • Creating

  • Created

  • Updating

  • Updated

  • Saving

  • Saved

  • Deleting

  • Deleted

  • Restoring

  • Restored

위 이벤트는 라라벨프레임워크의 모든 모델과 모델이 첨부된 비즈니스 로직에서 관찰할 수 있으며, 옵저버로부터 사용자 정의 이벤트(custom events)를 전달할 수 있고 application의 다른 파트에서 주시(listen) 할 수 도 있습니다.

 

아직 옵저버 클래스 사용하지 않았을 수도 있겠지만, 충분히 이해하고 있습니다.

 

옵저버 클래스를 만들려면 다음을 실행합니다:

php artisan make:observer <observerName>

(observerName을 관찰 중인 모델의 이름으로 바꿉니다)

그러면 라라벨의 app directory에 Observers 폴더가 생성되고, 옵저버 클래스가 저장됩니다.

<?php

namespace App\Observers;

class BankObserver
{
// an empty observer class
}

 

여기서부터 이전에 나열한 이벤트로 일치하는 메소드로 클래스를 채울 수 있습니다, 옵저버 작성할 때 다음과 같이 모델을 옵저버에게 첨부할 수 있습니다.

php artisan make:observer <observerName> -m <ModelName>

아래의 내용처럼 기본적으로 일부 메소드가 채워진 클래스가 작성됩니다.

<?php

namespace App\Observers;

use App\Task;

class Task
{
    /**
     * Handle the task "created" event.
     *
     * @param \App\Task $task
     * @return void
     */
    public function created(Task $task)
    {
//
    }

    /**
     * Handle the task "updated" event.
     *
     * @param \App\Task $task
     * @return void
     */
    public function updated(Task $task)
    {
//
    }

    /**
     * Handle the task "deleted" event.
     *
     * @param \App\Task $task
     * @return void
     */
    public function deleted(Task $task)
    {
//
    }

    /**
     * Handle the task "restored" event.
     *
     * @param \App\Task $task
     * @return void
     */
    public function restored(Task $task)
    {
//
    }

    /**
     * Handle the task "force deleted" event.
     *
     * @param \App\Task $task
     * @return void
     */
    public function forceDeleted(Task $task)
    {
//
    }
}

 

어떤 모델 액션이 어떤 옵저버 액션을 trigger 하는지 궁금할 것입니다. 다른 메소드들과 그 trigger를 간단히 설명하겠습니다.

  • Retrieved : 데이터베이스에서 모델 레코드를 검색할 때 이 옵저버 메서드를 호출합니다.

Model::findOrFail($id); // 옵저버 클래스에서 검색된 메소드를 trigger 합니다.

 

 

  • Creating : 모델의 레코드가 처리 중 이며, 아직 데이터베이스에 저장되지 않은 경우 호출 됩니다, id(primary key) 앞에 있으며, 모델에 대한 timestamp가 생성됩니다. 이 시점에서 column에 대한 기본값을 동적으로 확인하고 할당 할 수 있습니다.

  • Created : 모델 레코드가 성공적으로 생성한 후에 호출 됩니다. 만약 생성과정에서 에러가 발생하면 이 메서드는 호출되지 않습니다.

Model::create([]); // 처음 생성 메소드를 트리거 한 다음 옵저버 클래스에서 생성 된 메소드를 트리거합니다

 

 

  • Updating : 모델 레코드가 업데이트 프로세스에있을 때 호출되며, 업데이트가 데이터베이스에 저장 되기 전의 상태 입니다.

  • Updated : 모델 레코드에 성공적으로 업데이트 된 후에 호출 됩니다. 업데이트 과정에서 오류가 발생하면 해당 메소드를 호출하지 않습니다.

Model::update([]); // 먼저 creating 메소드가 트리거(triggers) 된 다음 옵저버 클래스에서 메소드가 생성 됩니다.

 

 

  • Saving and Saved : 이 방식은 스위스 군용 칼처럼 보일 수 있습니다. 데이터베이스에 대한 데이터의 지속성이 필요한 이벤트 전후에 호출되는데, 신규 레코드를 작성하는 경우 saving 메서드가 실행된 다음 creating, created 및 마지막으로 saved 메서드가 실행 됩니다. 모델 업데이트 시에도 saving, updating, updated 가 동일한 루틴(routine)으로 저장 됩니다.

  • Deleting : 모델 레코드가 삭제 프로세스에 있을 때 호출되며, 이 시점에 레코드가 데이터베이스에서는 아직 삭제 되지 않았으며, id를 사용하여 데이터베이스에서 검색하면, 적절한 데이터로 반환 됩니다.

  • Deleted : 모델 레코드가 성공적으로 삭제 된 후 호출 됩니다. 이 시점에서 레코드가 데이터베이스에서 삭제되었습니다.

Model::destroy($id);

 

 

  • Restoring and Restored : 이 메소드는 삭제된 모델 레코드가 복원될때 호출 됩니다. (SoftDelete 실행)

 

유의해야 할 사항:

  • updating 및 updated 메소드는 데이터베이스에서 변경된 컬럼이 있을때만 실행 됩니다, 따라서 업데이트 요청이 컬럼에 영향을 미치지 않으면 updaing 및 updated 옵저버가 트리거(trigger)되지 않고, 오직 saving 및 saved 메소드만 트리거(trigger) 됩니다.

  • 삭제된 레코드를 복원 할 때,  위 메소드들이 차례로 트리거(trigger)되고 검색 되면서, retrieved, restoring, saving, updating, updated, saved 의 작업을 처리할 수 있습니다.

옵저버 메소드를 사용하지 않고, 모델 이벤트를 만들어 옵저버 이벤트없이 저장할 수 있습니다. 

public function saveQuietly(array $options = [])
{
	return static::withoutEvents(
		function () use ($options) {
			return $this->save($options);
		}
	);
}
// Note: 이 메소드는 해당 모델을 추가 해야 합니다.

필요에 따라 다른 모델 이벤트에 맞게 리팩토링 할 수 있습니다.
마지막으로 마지막 부분은 옵저버의 특정 모델에 바인딩(binding)을 합니다.
이것은 AppServiceProvider 클래스의 boot 메소드에서 수행 할 수 있습니다.

/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
	Model::observe(Observer::class);
}
// Model is the model to be observed and observer is the observer class

라라벨 옵저버에 대한 소개가 끝났습니다. and I hope it was enlightening to you.

Follow me on twitter: https://twitter.com/drumzminister

 

 

※ 번역 간 애매하고 이상한 문장, 혹은 더 나은 문장이 있으신 경우 코멘트 주시면 처리하겠습니다.

'번역' 카테고리의 다른 글

App::bind 와 App::singleton의 차이점  (2) 2020.06.24
Comments