13.x와 Framework v13.36.0의 구현을 참조합니다. 일반적인 미들웨어 작성법은 미들웨어를 참조하세요.
등록·적용·실행을 구분한다
Router::aliasMiddleware()는 별칭을 키, 클래스명을 값으로 하여 Router의 배열에 등록합니다. 미들웨어의 인스턴스 생성이나 라우트에 대한 적용은 수행하지 않습니다.
별칭 이름은 공개 API입니다.
auth나 throttle 같은 내장 이름, 다른 패키지와 충돌하기 쉬운 일반적인 이름을 피하고 패키지 고유의 접두사를 붙입니다. 같은 키로 다시 등록하면 aliasMiddleware()는 이전 대응을 덮어씁니다.
프로바이더에서 별칭을 공개한다
다음 예에서는 응답에 고정된 식별 헤더를 붙이는 미들웨어를 만듭니다. 인증·인가나 접근 제어의 예가 아닙니다. Composer의 PSR-4에서Acme\Courier\를 src/에 대응시키고, 프로바이더를 자동 검출 또는 수동으로 등록하는 것을 전제로 합니다.
src/Http/Middleware/AddCourierHeader.php
boot()에서 사용합니다. boot()의 인수는 서비스 컨테이너에서 주입되므로, 미들웨어 등록을 위해 사용자의 bootstrap/app.php를 자동으로 편집할 필요는 없습니다.
src/CourierServiceProvider.php
사용자가 라우트 단위로 적용한다
사용하는 애플리케이션의routes/web.php에서 필요한 라우트에만 할당합니다.
routes/web.php
->middleware(AddCourierHeader::class)처럼 클래스명을 직접 지정할 수도 있습니다. 짧은 이름을 사용자에게 제공할 필요가 있는지에 따라 선택합니다.
패키지 자체가 라우트를 제공하는 경우에도 라우트 파일에서 필요한 미들웨어를 명시합니다. loadRoutesFrom()은 web이나 api를 자동으로 추가하지 않습니다. 등록 방법과 라우트 캐시의 처리는 패키지의 라우트 등록과 캐시를 참조하세요.
애플리케이션 전체에 대한 적용은 사용자가 선택한다
사용하는 애플리케이션의 모든web 라우트에 적용하고 싶은 경우에는, 사용자가 기존 withMiddleware() 콜백에 다음 설정을 추가합니다. 기존 설정을 대체하는 예가 아닙니다.
web 그룹이며 글로벌 스택이 아닙니다. api나 어느 그룹도 붙어 있지 않은 라우트에는 자동으로 적용되지 않습니다.
Router의 그룹 조작에는 차이가 있다
패키지가 고유한 그룹을 제공하는 경우에는 고유한 이름을 사용합니다. 다음은 프로바이더의boot(Router $router) 안에 두는 예입니다.
->middleware('acme-courier')로 적용할 수 있습니다. 단, 이 그룹에 포함되는 것은 지정한 클래스뿐이며, web의 세션이나 CSRF 보호를 이어받는 것은 아닙니다.
기존 그룹에 추가하는 API도 있지만, v13.36.0의 Router 구현에는 다음과 같은 차이가 있습니다.
middlewareGroup('web', [...])로 패키지의 클래스만 설정하면 기존 web의 내용을 대체해 버립니다. 추가용 메서드와 혼동하지 마세요. 또한 존재하지 않는 web에 pushMiddlewareToGroup()을 해도 표준 web 그룹이 복원되는 것은 아닙니다.
추가용 메서드의 중복 판정은 등록한 값에 대한 것입니다. 같은 클래스를 가리키는 별칭과 클래스명은 서로 다른 문자열이므로, 등록 테이블 단계에서는 별개의 항목이 됩니다. 표기를 통일하고, 표기가 다른 동일 클래스까지 등록 시에 중복 제거된다고 가정하지 마세요.
등록 순서만으로 실행 순서를 보장하지 않는다
Router는 라우트에 할당된 미들웨어의 별칭과 그룹을 전개하고, 제외를 처리한 후 우선순위로 정렬합니다. 앞·끝에 추가하는 것만으로 인증이나 라우트 모델 바인딩과의 엄밀한 전후 관계가 보장되는 것은 아닙니다. 또한 HTTP Kernel의syncMiddlewareToRouter()는 Kernel이 가진 그룹을 Router에 middlewareGroup()으로 동기화합니다. Kernel 측의 구성이 나중에 다시 동기화되면 Router에 직접 추가한 그룹의 내용이 대체되는 경우가 있습니다. 패키지 간의 기동 순서로 기존 그룹의 변경을 경쟁하는 것이 아니라, 사용하는 애플리케이션 측의 withMiddleware()에서 구성을 집약하는 방침을 기본으로 합니다.
세션 시작 후, 인증 후 등의 순서가 필요한 기능에서는 그 전제를 설치 절차에 명시하고, 사용하는 애플리케이션의 우선순위 설정과 함께 확인합니다. 패키지가 애플리케이션 전체의 우선순위 목록을 통째로 대체하는 것은 피하세요.
캐시와 검증의 경계
별칭 등록을routesAreCached()의 조건 안이나 라우트 파일에 두지 마세요. loadRoutesFrom()은 캐시가 있으면 라우트 파일을 읽어 들이지 않지만, 캐시된 라우트에 남아 있는 별칭을 실행 시에 해석하기 위한 등록은 필요합니다. 프로바이더의 boot()에서 매번 등록합니다.
라우트에 대한 할당을 변경한 경우에는 사용하는 애플리케이션에서 라우트 캐시를 다시 생성합니다.
-vv는 그룹의 내용을 전개하여 확인하기 위해 사용합니다. 단, 목록 표시가 성공하더라도 미들웨어 내의 처리나 세션 사용까지 보장하는 것은 아닙니다. HTTP 요청 테스트도 필요합니다.
다음은 위의 /courier-status를 정의한 Laravel 애플리케이션의 Feature 테스트에 추가하는 메서드입니다.
그룹의 존재 확인이나 별칭 배열을 조사하는 단위 테스트와 실제 HTTP 실행은 별개의 검증입니다. 특히 캐시 검증은 같은 프로세스의 Router를 살펴보는 것만이 아니라, 캐시 생성 후 새로운 기동에서 수행합니다. 장수명 워커를 사용하고 있는 경우에는 일반 배포 절차에 따라 다시 로드하세요.
관련 페이지
미들웨어
작성, 라우트에 대한 적용, 파라미터, 우선순위의 기본을 확인합니다.
패키지의 라우트 등록과 캐시
라우트 로딩과 캐시 생성 시 설정의 관계를 확인합니다.