파사드
업데이트됨번역일: 2026년 10월 3일
이 페이지는 원문이 업데이트되어 번역이 갱신되었습니다.
- 원문 수정
- 2026년 10월 3일
- 번역 갱신
- 2026년 10월 3일
파사드
소개
Laravel 문서 곳곳에서 "파사드(facade)"를 통해 Laravel의 기능과 상호작용하는 코드 예제를 보게 될 것입니다. 파사드는 애플리케이션의 서비스 컨테이너에 등록된 클래스에 "정적(static)" 방식으로 접근할 수 있는 인터페이스를 제공합니다. Laravel에는 거의 모든 핵심 기능에 접근할 수 있는 다양한 파사드가 기본으로 포함되어 있습니다.
Laravel의 파사드는 서비스 컨테이너에 등록된 실제 클래스에 대한 "정적 프록시" 역할을 합니다. 그 덕분에 간결하고 표현력 있는 문법을 사용하면서도, 전통적인 정적 메서드보다 테스트하기 쉽고 유연한 구조를 유지할 수 있습니다. 파사드가 내부적으로 어떻게 동작하는지 당장 완벽히 이해하지 못해도 괜찮습니다 — 일단 사용해 보면서 자연스럽게 Laravel을 익혀 나가면 됩니다.
Laravel의 모든 파사드는 Illuminate\Support\Facades 네임스페이스에 정의되어 있습니다. 다음과 같이 손쉽게 파사드에 접근할 수 있습니다.
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Route;
Route::get('/cache', function () {
return Cache::get('key');
});이 문서 전반에 걸쳐, 많은 예제가 프레임워크의 다양한 기능을 설명할 때 파사드를 활용합니다.
헬퍼 함수
파사드를 보완하기 위해 Laravel은 자주 쓰이는 기능을 더욱 간편하게 사용할 수 있도록 다양한 전역 "헬퍼 함수"를 제공합니다. 자주 접하게 될 헬퍼 함수로는 view, response, url, config 등이 있습니다. Laravel이 제공하는 각 헬퍼 함수는 관련 기능을 설명하는 문서 안에 함께 소개되어 있으며, 전체 목록은 헬퍼 함수 문서에서 확인할 수 있습니다.
예를 들어 JSON 응답을 생성할 때 Illuminate\Support\Facades\Response 파사드 대신 response 함수를 간단히 사용할 수 있습니다. 헬퍼 함수는 전역에서 바로 사용할 수 있으므로 별도로 클래스를 import할 필요가 없습니다.
use Illuminate\Support\Facades\Response;
Route::get('/users', function () {
return Response::json([
// ...
]);
});
Route::get('/users', function () {
return response()->json([
// ...
]);
});파사드는 언제 사용해야 할까
파사드에는 여러 장점이 있습니다. 긴 클래스 이름을 일일이 기억하거나 수동으로 주입·설정하지 않고도 간결하고 기억하기 쉬운 문법으로 Laravel의 기능을 사용할 수 있습니다. 또한 PHP의 동적 메서드 기능을 활용하는 독특한 구조 덕분에 테스트 작성도 어렵지 않습니다.
다만 파사드를 사용할 때는 주의할 점이 있습니다. 파사드의 가장 큰 위험 요소는 클래스의 "책임 범위가 비대해지는 것(scope creep)"입니다. 파사드는 사용하기 쉽고 별도의 주입 과정이 필요 없기 때문에, 자칫하면 하나의 클래스 안에 너무 많은 파사드를 끌어다 쓰면서 클래스가 계속 비대해질 수 있습니다. 반면 의존성 주입 방식에서는 생성자가 점점 길어지는 것이 눈에 보이기 때문에 "클래스가 너무 커지고 있다"는 시각적 경고 신호를 얻을 수 있습니다. 따라서 파사드를 사용할 때는 클래스의 크기와 책임 범위에 더욱 신경 써야 합니다. 클래스가 너무 비대해지고 있다면 여러 개의 작은 클래스로 분리하는 것을 고려해 보세요.
파사드 vs. 의존성 주입
의존성 주입의 주요 장점 중 하나는 주입된 클래스의 구현체를 다른 것으로 쉽게 교체할 수 있다는 점입니다. 이는 테스트 시 모의 객체(mock)나 스텁(stub)을 주입하고, 스텁에서 특정 메서드가 호출되었는지 단언(assert)할 수 있다는 점에서 유용합니다.
일반적으로 진짜 정적 메서드는 모킹하거나 스텁으로 대체하기 어렵습니다. 하지만 파사드는 동적 메서드를 이용해 서비스 컨테이너에서 해석(resolve)한 객체로 메서드 호출을 프록시하기 때문에, 주입된 클래스 인스턴스를 테스트하는 것과 거의 동일한 방식으로 파사드를 테스트할 수 있습니다. 예를 들어 다음과 같은 라우트가 있다고 가정해 봅시다.
use Illuminate\Support\Facades\Cache;
Route::get('/cache', function () {
return Cache::get('key');
});Laravel의 파사드 테스트 메서드를 사용하면 Cache::get 메서드가 예상한 인자로 호출되었는지 검증하는 테스트를 다음과 같이 작성할 수 있습니다.
Pest
use Illuminate\Support\Facades\Cache;
test('basic example', function () {
Cache::shouldReceive('get')
->with('key')
->andReturn('value');
$response = $this->get('/cache');
$response->assertSee('value');
});PHPUnit
use Illuminate\Support\Facades\Cache;
/**
* A basic functional test example.
*/
public function test_basic_example(): void
{
Cache::shouldReceive('get')
->with('key')
->andReturn('value');
$response = $this->get('/cache');
$response->assertSee('value');
}파사드 vs. 헬퍼 함수
파사드 외에도 Laravel은 뷰 생성, 이벤트 발생, Job 디스패치, HTTP 응답 전송 같은 흔한 작업을 간편하게 처리할 수 있는 다양한 "헬퍼" 함수를 제공합니다. 이 헬퍼 함수 중 상당수는 대응되는 파사드와 완전히 동일한 기능을 수행합니다. 예를 들어 다음 두 코드는 서로 동등합니다.
return Illuminate\Support\Facades\View::make('profile');
return view('profile');파사드와 헬퍼 함수 사이에는 실질적인 차이가 전혀 없습니다. 헬퍼 함수를 사용하더라도 대응되는 파사드와 동일한 방식으로 테스트할 수 있습니다. 예를 들어 다음과 같은 라우트가 있다고 가정해 봅시다.
Route::get('/cache', function () {
return cache('key');
});cache 헬퍼는 내부적으로 Cache 파사드가 가리키는 클래스의 get 메서드를 호출합니다. 따라서 헬퍼 함수를 사용하더라도 다음과 같이 예상한 인자로 메서드가 호출되었는지 검증하는 테스트를 작성할 수 있습니다.
use Illuminate\Support\Facades\Cache;
/**
* A basic functional test example.
*/
public function test_basic_example(): void
{
Cache::shouldReceive('get')
->with('key')
->andReturn('value');
$response = $this->get('/cache');
$response->assertSee('value');
}파사드의 동작 원리
Laravel 애플리케이션에서 파사드는 컨테이너에 등록된 객체에 접근할 수 있게 해 주는 클래스입니다. 이 동작을 가능하게 하는 핵심 장치는 Facade 클래스에 들어 있습니다. Laravel이 제공하는 파사드는 물론, 여러분이 직접 만드는 커스텀 파사드도 모두 기본 클래스인 Illuminate\Support\Facades\Facade를 상속합니다.
Facade 기본 클래스는 PHP의 매직 메서드 __callStatic()을 활용해, 파사드로 들어온 호출을 컨테이너에서 해석한 객체로 그대로 위임(defer)합니다. 아래 예제는 Laravel의 캐시 시스템을 호출하는 코드입니다. 코드만 봐서는 Cache 클래스에 정적 메서드 get이 정의되어 있는 것처럼 보일 수 있습니다.
<?php
namespace App\Http\Controllers;
use Illuminate\Support\Facades\Cache;
use Illuminate\View\View;
class UserController extends Controller
{
/**
* Show the profile for the given user.
*/
public function showProfile(string $id): View
{
$user = Cache::get('user:'.$id);
return view('profile', ['user' => $user]);
}
}파일 상단에서 Cache 파사드를 import하고 있는 부분을 주목하세요. 이 파사드는 Illuminate\Contracts\Cache\Factory 인터페이스의 실제 구현체에 접근하기 위한 프록시 역할을 합니다. 파사드를 통해 호출되는 모든 메서드는 실제로 Laravel 캐시 서비스의 내부 인스턴스로 전달됩니다.
실제로 Illuminate\Support\Facades\Cache 클래스를 열어 보면, 정적 메서드 get이 정의되어 있지 않다는 것을 알 수 있습니다.
class Cache extends Facade
{
/**
* Get the registered name of the component.
*/
protected static function getFacadeAccessor(): string
{
return 'cache';
}
}대신 Cache 파사드는 기본 Facade 클래스를 상속하면서 getFacadeAccessor() 메서드를 정의합니다. 이 메서드의 역할은 서비스 컨테이너 바인딩의 이름을 반환하는 것입니다. 누군가 Cache 파사드의 정적 메서드를 호출하면, Laravel은 서비스 컨테이너에서 cache 바인딩을 해석한 뒤, 요청된 메서드(여기서는 get)를 그 객체에 대해 실행합니다.
실시간 파사드
실시간 파사드(real-time facades)를 사용하면 애플리케이션 내 어떤 클래스든 마치 파사드처럼 다룰 수 있습니다. 어떻게 활용되는지 알아보기 위해, 먼저 실시간 파사드를 사용하지 않는 코드를 살펴보겠습니다. 예를 들어 Podcast 모델에 publish 메서드가 있다고 가정해 봅시다. 팟캐스트를 발행하려면 Publisher 인스턴스를 주입해야 합니다.
<?php
namespace App\Models;
use App\Contracts\Publisher;
use Illuminate\Database\Eloquent\Model;
class Podcast extends Model
{
/**
* Publish the podcast.
*/
public function publish(Publisher $publisher): void
{
$this->update(['publishing' => now()]);
$publisher->publish($this);
}
}메서드에 퍼블리셔 구현체를 주입하면, 주입된 퍼블리셔를 모킹할 수 있으므로 이 메서드를 독립적으로 테스트하기 쉬워집니다. 다만 publish 메서드를 호출할 때마다 매번 퍼블리셔 인스턴스를 전달해야 한다는 번거로움이 있습니다. 실시간 파사드를 사용하면 동일한 테스트 용이성을 유지하면서도 Publisher 인스턴스를 명시적으로 전달할 필요가 없어집니다. 실시간 파사드를 생성하려면, import하는 클래스의 네임스페이스 앞에 Facades를 붙이면 됩니다.
<?php namespace App\Models; use App\Contracts\Publisher; //use Facades\App\Contracts\Publisher; //use Illuminate\Database\Eloquent\Model; class Podcast extends Model{ /** * Publish the podcast. */ public function publish(Publisher $publisher): void // public function publish(): void // { $this->update(['publishing' => now()]); $publisher->publish($this); // Publisher::publish($this); // }}실시간 파사드를 사용하면, Facades 접두사 뒤에 오는 인터페이스나 클래스 이름을 기준으로 서비스 컨테이너에서 퍼블리셔 구현체를 해석합니다. 테스트할 때는 Laravel에 내장된 파사드 테스트 헬퍼를 사용해 이 메서드 호출을 모킹할 수 있습니다.
Pest
<?php
use App\Models\Podcast;
use Facades\App\Contracts\Publisher;
use Illuminate\Foundation\Testing\RefreshDatabase;
pest()->use(RefreshDatabase::class);
test('podcast can be published', function () {
$podcast = Podcast::factory()->create();
Publisher::shouldReceive('publish')->once()->with($podcast);
$podcast->publish();
});PHPUnit
<?php
namespace Tests\Feature;
use App\Models\Podcast;
use Facades\App\Contracts\Publisher;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
class PodcastTest extends TestCase
{
use RefreshDatabase;
/**
* A test example.
*/
public function test_podcast_can_be_published(): void
{
$podcast = Podcast::factory()->create();
Publisher::shouldReceive('publish')->once()->with($podcast);
$podcast->publish();
}
}파사드 클래스 레퍼런스
아래 표는 각 파사드와 그 파사드가 가리키는 실제 클래스를 정리한 것입니다. 특정 파사드에 대한 API 문서를 빠르게 찾아볼 때 유용하게 활용할 수 있습니다. 해당되는 경우 서비스 컨테이너 바인딩 키도 함께 표기했습니다.