Laravel 개발자 가이드
한눈에 보기
섹션 제목: “한눈에 보기”Laravel 패키지는 핵심 문서 수명 주기를 변경하지 않고 NextPDF를 Laravel 관례에 맞게 조정합니다. 컨테이너는 공유 레지스트리와 팩토리를 소유합니다. 각 PDF 문서는 일회용이며 한 번만 빌드, 반환, 스트리밍 또는 저장해야 합니다.
애플리케이션 서비스, 큐 작업, 응답 흐름 또는 테스트 커버리지를 nextpdf/laravel 중심으로 설계할 때 이 가이드를 사용하십시오.
아키텍처 경계
섹션 제목: “아키텍처 경계”| 계층 | 소유 주체 | 책임 | 여기에 두지 말 것 |
|---|---|---|---|
| 컨트롤러 | 애플리케이션 | 요청을 인가하고 문서 빌더를 선택한 뒤 응답을 반환합니다. | 여러 사용 사례에서 공유되는 PDF 레이아웃 규칙. |
| 애플리케이션 서비스 | 애플리케이션 | 도메인 데이터를 수집하고 문서 빌드 코드를 호출합니다. | 컨테이너 부팅 로직 또는 패키지 구성. |
| 문서 빌더 | 애플리케이션 | 도메인 데이터를 NextPDF 문서 호출로 변환합니다. | 요청 객체, Eloquent 쿼리 로직 또는 큐 전송 세부 사항. |
| Laravel 통합 | nextpdf/laravel | 팩토리, 레지스트리, 서명자, TSA 클라이언트, 파사드, 응답 및 큐 작업을 바인딩합니다. | 비즈니스별 스토리지 경로 또는 테넌트 정책. |
| 핵심 엔진 | nextpdf/nextpdf | PDF를 빌드하고 직렬화합니다. | Laravel 응답, 큐 또는 파일 시스템 정책. |
런타임 수명 주기
섹션 제목: “런타임 수명 주기”| 단계 | 동작 | 개발자 작업 |
|---|---|---|
| 서비스 프로바이더 등록 | NextPdfServiceProvider::register()는 공유 레지스트리, 문서 팩토리, 문서 바인딩, HTTP 클라이언트, TSA 클라이언트, 서명자 및 선택적 전자 인보이스 계약을 등록합니다. | 프로덕션 전에 config/nextpdf.php를 게시하고 검토하십시오. |
| 문서 확인(resolution) | 이 단계에서 Pdf 파사드와 PdfDocumentInterface 바인딩은 DocumentFactoryInterface를 통해 새 문서를 확인합니다. | 요청, 명령 또는 큐에 추가된 작업마다 문서를 한 번만 확인하십시오. |
| 작성 | 애플리케이션 코드는 파사드 또는 주입된 문서를 통해 핵심 문서 API를 호출합니다. | 도메인 데이터 추출은 문서 빌더 외부에서 처리하십시오. |
| 최종 출력 | PdfResponse가 HTTP 출력을 내보내거나 문서가 디스크에 저장됩니다. | 문서당 최종 출력 경로를 하나만 선택하십시오. |
| 큐 실행 | GeneratePdfJob는 워커 내부에서 문서를 다시 빌드하고 출력 경로를 다시 검증합니다. | 스칼라 컨텍스트를 전달하고 콜백은 멱등하게 유지하십시오. |
권장 애플리케이션 구조
섹션 제목: “권장 애플리케이션 구조”| 경로 | 용도 |
|---|---|
app/Pdf/Builders/* | 순수 문서 빌더. 데이터를 받아 완성된 문서를 반환합니다. |
app/Pdf/Data/* | 이미 인가된 문서 입력을 전달하는 작은 DTO. |
app/Services/* | 애플리케이션 오케스트레이션, 쿼리, 인가 핸드오프 및 스토리지 경로 선택. |
app/Jobs/* | 애플리케이션에 명명된 작업이 필요할 때 GeneratePdfJob을 감싸는 선택적 래퍼. |
tests/Feature/Pdf/* | HTTP 응답, 큐 디스패치 및 인가 테스트. |
tests/Unit/Pdf/* | 작은 결정론적 입력을 사용하는 빌더 테스트. |
빌더는 Laravel 요청 객체와 독립적으로 유지하십시오. 빌더는 컨트롤러, 명령, 테스트 및 큐 워커에서 동일한 입력으로 호출할 수 있어야 합니다.
<?php
namespace App\Pdf\Builders;
use App\Pdf\Data\InvoicePdfData;use NextPDF\Contracts\PdfDocumentInterface;
final readonly class InvoicePdfBuilder{ public function build(PdfDocumentInterface $pdf, InvoicePdfData $data): PdfDocumentInterface { $pdf->setTitle($data->title) ->addPage() ->setFont('dejavusans', '', 12) ->writeHtml($data->html);
return $pdf; }}동기 응답 패턴
섹션 제목: “동기 응답 패턴”PDF 흐름이 애플리케이션 로직의 일부라면 생성자 주입을 사용하십시오. 파사드는 정적 스타일이 가독성을 높이는 짧은 컨트롤러 흐름에서만 사용하십시오.
<?php
namespace App\Http\Controllers;
use App\Pdf\Builders\InvoicePdfBuilder;use App\Pdf\Data\InvoicePdfData;use NextPDF\Contracts\PdfDocumentInterface;use NextPDF\Laravel\Http\PdfResponse;
final readonly class DownloadInvoiceController{ public function __invoke( PdfDocumentInterface $pdf, InvoicePdfBuilder $builder, ) { $document = $builder->build( $pdf, InvoicePdfData::fromInvoiceId(1234), );
return PdfResponse::download($document, 'invoice-1234.pdf'); }}응답 헬퍼는 Laravel 응답을 빌드하기 전에 문서 바이트를 구체화합니다. 이들은 응답 헬퍼이지 백그라운드 렌더러가 아닙니다.
큐 패턴
섹션 제목: “큐 패턴”GeneratePdfJob은 빌더 콜러블과 출력 경로를 받습니다. 작업은 실행 시점에 안전하지 않은 경로를 검증합니다. 그래도 애플리케이션 코드는 디스패치 전에 테넌트에 안전한 스토리지 루트를 선택해야 합니다.
<?php
use App\Pdf\Builders\QueuedInvoiceBuilder;use NextPDF\Laravel\Jobs\GeneratePdfJob;
GeneratePdfJob::dispatch( outputPath: storage_path('app/pdfs/invoice-1234.pdf'), builder: [QueuedInvoiceBuilder::class, 'build'],)->onQueue(config('nextpdf.queue.queue', 'pdf'));큐 콜백은 작아야 합니다. 복잡한 클로저를 큐 페이로드에 저장하기보다는 애플리케이션 작업 리스너에서 영구 상태를 기록하는 방식을 선호하십시오.
확장 지점
섹션 제목: “확장 지점”| 확장 지점 | 사용 목적 | 제약 조건 |
|---|---|---|
PdfDocumentInterface 바인딩 | 애플리케이션 전역 기본값을 적용하기 위해 문서 생성을 교체하거나 데코레이트합니다. | 새 문서 인스턴스를 반환해야 합니다. |
DocumentFactoryInterface | 서비스와 테스트에서 명시적으로 새 문서를 생성합니다. | 반환된 문서를 캐시하지 마십시오. |
config/nextpdf.php | 기본값, 큐 설정, Chrome 렌더러 설정, 서명 후크, TSA, OCSP 캐시. | 환경 변수를 요청 입력이 아닌 배포 구성으로 취급하십시오. |
GeneratePdfJob 빌더 | 문서를 비동기적으로 빌드합니다. | 콜러블은 Laravel의 큐 전송으로 직렬화할 수 있어야 합니다. |
| 성공/실패 콜백 | 생성 후 알림 또는 정리. | 콜백을 멱등하게 유지하고 부작용을 고려하십시오. |
| 선택적 Premium 계약 | 전자 인보이스 임베더, 검증기, 프로필 및 Schematron 러너. | 선택적 패키지가 설치되고 라이선스가 부여된 경우에만 확인하십시오. |
개발 워크플로
섹션 제목: “개발 워크플로”- 컨트롤러 또는 기능 테스트에서 첫 번째 문서를 동기적으로 빌드합니다.
- 레이아웃 코드를
app/Pdf/Builders아래의 빌더 클래스로 이동합니다. - 쿼리 및 인가 로직을 애플리케이션 서비스로 이동합니다.
- 헤더와 파일 이름에 대한
PdfResponse테스트를 추가합니다. - 느리거나 대용량인 생성 작업을
GeneratePdfJob으로 이동합니다. - 직렬화된 컨텍스트, 출력 경로 정책 및 실패 처리에 대한 큐 테스트를 추가합니다.
- 대표적인 프로덕션 데이터로 메모리와 렌더링 시간을 측정합니다.
실패 처리
섹션 제목: “실패 처리”| 실패 | 처리 위치 | 권장 대응 |
|---|---|---|
| 잘못된 요청 또는 인가되지 않은 문서 | 컨트롤러 또는 정책. | 일반적인 애플리케이션 인가 또는 검증 응답을 반환합니다. |
| 누락된 글꼴 또는 잘못된 이미지 | 빌더 테스트 및 애플리케이션 로깅. | 요청 또는 작업을 실패 처리하십시오. 부분 PDF를 내보내지 마십시오. |
| 안전하지 않은 출력 경로 | 애플리케이션 스토리지 서비스 및 GeneratePdfJob. | 디스패치 전에 거부하고 심층 방어로서 워커 측 검증에 의존하십시오. |
| 서명 또는 TSA 실패 | 서명 서비스 경계. | 문서를 서명하지 않은 상태로 둘 수 있는지 결정하십시오. 규제 대상 문서는 기본적으로 fail closed로 처리하십시오. |
| 큐 타임아웃 | 큐 워커 구성 및 관찰 가능성. | 빌더가 결정론적이고 출력 경로를 덮어쓰는 것이 안전한 경우에만 재시도하십시오. |
안전한 기본값
섹션 제목: “안전한 기본값”| 관심사 | 기본값 | 재정의 시점 |
|---|---|---|
| 큐 이름 | pdf | 생성이 사용자 대면 작업과 경합할 때는 전용 큐를 사용하십시오. |
| 작업 타임아웃 | 120초 | 문서 크기와 워커 용량을 측정한 후에만 늘리십시오. |
| 응답 파일 이름 | document.pdf | 정제된 비즈니스 식별자를 사용하십시오. |
| 글꼴 레지스트리 | 워밍업 후 공유되고 잠깁니다. | 핫 패스에서 사용되는 글꼴에 대해 preload_fonts를 추가하십시오. |
| 이미지 레지스트리 | 공유되는 제한된 크기의 캐시. | 메모리가 제한된 워커의 경우 image_cache_mb를 낮추십시오. |
| 스트리밍 응답 청킹 | 64KB 청크. | 청크 경계에 의존하지 마십시오. 이는 출력 세부 사항입니다. |
테스트 체크리스트
섹션 제목: “테스트 체크리스트”- 컨트롤러 테스트는
Content-Type,Content-Disposition및 방어적 헤더를 검증합니다. - 빌더 테스트는 결정론적 DTO를 사용하며 데이터베이스를 쿼리하지 않습니다.
- 큐 테스트는 빌더가 새 문서를 받는지 검증합니다.
- 경로 테스트는 트래버설, 스트림 래퍼, 널 바이트 및
.pdf가 아닌 파일 거부를 다룹니다. - 워커 테스트는 프로덕션과 동일한 메모리 제한에서 대표적인 문서를 렌더링합니다.
- 선택적 서명 테스트는 누락된 인증서, 잘못된 암호, TSA 사용 불가 및 구성된 서명 수준을 다룹니다.