65호. 라라벨 6.1.0 에 추가된 기능 소개 free

2019-10-02

라라벨 6.1.0이 배포됐습니다. 추가된 기능이 많네요!



  • LazyCollection에 eager() 매서드 추가 (#29832)

  • 개별 로그 드라이버/채널 제거 기능 추가 (#30132, a52a0dd)

  • TestResponse에 assertNoContent() 매서드 추가 (#30125)

  • 노티피케이션 큐용 잡 미들웨어 추가 (#30070)

  • SendQueueNotifications에 InteractsWithQueue 추가 (#30140)

  • 노티피케이션 큐 재전송 허용 시간 설정 기능 추가 (#30141)

  • 테스트 리퀘스트에 쿠키 첨부 매서드 추가 (#30101)


LazyCollection에 eager() 매서드 추가


공식적인 기능 설명은 "모든 아이템을 eager 로드해서 배열로 만들고 이를 새 레이지 컬렉션을 만든다. (Eager load all items into a new lazy collection backed by an array.)" 입니다.


코드로 보면 전체 아이템을 호출해서 새로운 레이지 컬렉션을 만들어 반환합니다.


public function eager()
{
return new static($this->all());
}

원래 레이지 컬렉션의 용도는 대량의 데이터를 적은 메모리로 처리하기 위한 것입니다(자세한 사항은 1일 1식 라라벨 51호 - 라라벨 6, 레이지 컬렉션을 참고하세요). 그런데 전체 데이터를 한 번에 불러들인다고 하니 다소 의아하네요. 이 코드를 추가한 사람은 아래의 코드를 예로 들었는데, 아래의 코드는 쿼리를 한 번만 날리는 반면, eager()를 하지 않으면 두 번을 날린다고 합니다.


$users = User::cursor();

$users = $users->eager();

$count = $users->count();

$users->each(function ($user) {
//
});

얼핏 N+1 문제를 해결하기 위해 쓰는 eager 로드와 비슷해보이지만 개념이나 용도가 좀 다르게 느껴져서 저는 아직 어느 상황에 써야할지 정확하게 느낌이 오진 않네요.


원래는 eager()가 아니라 cache()라는 매서드명으로 만들어졌다가 논의를 통해 바뀐건데, 저는 오히려 cache()가 좀 더 적절한 것 같아요. 테스트 코드를 보면 더 그런 느낌을 받습니다. 아래는 이 기능과 함께 추가된 테스트 코드인데, 일부러 아직 eager()로 바꾸기 전의 코드를 가져와봤습니다.


public function testCache() // 나중에 testEager()로 바뀜
{
$source = [1, 2, 3, 4, 5];

$data = LazyCollection::make(function () use (&$source) {
yield from $source;
})->cache(); // 나중에 ->eager()로 바뀜

$source[] = 6;

$this->assertSame([1, 2, 3, 4, 5], $data->all());
}

혹시 용도가 뽝 떠오르시는 분들은 제게 힌트 좀 주세요.


개별 로그 드라이버/채널 제거 기능 추가


DatabaseManagerpurge() 매서드가 있는 것에 영감을 받아서 LogManager에도 purge() 매서드를 추가했다고 합니다. 사용방법은 테스트 코드를 참고하면 될 것 같아요.


public function testLogMnagerPurgeResolvedChannels()
{
$manager = new LogManager($this->app);
$this->assertEmpty($manager->getChannels());

$manager->channel('single')->getLogger();
$this->assertCount(1, $manager->getChannels());

$manager->purge('single');
$this->assertEmpty($manager->getChannels());
}

TestResponse에 assertNoContent() 매서드 추가


컨텐트가 없는 상황을 기존엔 두 개의 매서드로 확인하던 걸 하나의 매서드로 확인 할 수 있습니다.


Before


$response = $this->get('api/endpoint');

$response->assertStatus(409);
$this->assertEmpty($response->content());

After


$response = $this->get('api/endpoint');

$response->assertNoContent(409);

assertNoContent()에 상태코드를 넘겨주지 않아도 되며, 기본 상태값은 204입니다.


노티피케이션 큐용 잡 미들웨어 추가


잡 큐 미들웨어는 있었지만 노티피케이션 큐는 지원이 안됐었습니다. (#30057) 이제 큐를 사용하는 노티피케이션에도 잡 미들웨어를 적용할 수 있다고 하네요.


잡 미들웨어와 마찬가지로 through() 매서드로 적용합니다.


class Notification extends BaseNotification implements ShouldQueue
{
use Queueable;
}

$user = User::find(2);
$notification = (new Notification())->through(new RateLimited);
$user->notify($notification);

혹은 노티피케이션 클래스에 middleware() 매서드로 추가할 수도 있습니다.


public function middleware()
{
return [new SomeMiddleware];
}

노티피케이션 큐 재전송 허용 시간 설정 기능 추가


SendQueueNotificationsretryUntil() 혹은 timeoutAt 프로퍼티를 정의해서 재전송을 언제까지 허용할건지 설정할 수 있게 되었습니다.


테스트 리퀘스트에 쿠키 첨부 매서드 추가


기존에는 테스트 리퀘스트에 쿠키를 넣어서 보내려면 call() 매서드를 써야했는데, withCookies()로 더 편하게 쿠키를 첨부할 수 있게 되었습니다.


Before


$cookies = [
'name1' => encrypt('value1'),
'name2' => encrypt('value2')
];
$response = $this->call('get', 'test', [], $cookies);

After


$response = $this->withCookies([
'name1' => 'value1',
'name2' => 'value2'
])->get('test');

withCookie()disableCookieEncryption()도 추가되었습니다.



  • withCookie: 첨부할 쿠키 항목이 하나일 때 사용

  • disableCookieEncryption: 암호화를 비활성화하고 싶을 때 사용


1일 1식 라라벨 65호

2019년 10월 2일


이현석

메쉬 코리아 개발자. 바쁜 팀장님 대신 알려주는 신입 PHP 개발자 안내서를 쓰고, 클린 아키텍처 인 PHP를 번역했습니다. 2020년에 출간될 Laravel Up & Running 2nd Edition을 번역하고 있습니다.