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 を公開して確認してください。 |
| ドキュメントの resolve(解決) | 新しいドキュメントは、Pdf ファサードと PdfDocumentInterface バインディングから DocumentFactoryInterface 経由で解決されます。 | リクエスト、コマンド、またはキュー投入されたジョブごとに、ドキュメントを一度だけ解決します。 |
| オーサリング | アプリケーションコードは、ファサードまたは注入されたドキュメントインスタンスを通じてコアのドキュメント API を呼び出します。 | ドメインデータの抽出はドキュメントビルダーの外部で行ってください。 |
| 終端出力 | PdfResponse が HTTP 出力を発行するか、ドキュメントがディスクに保存されます。 | ドキュメントごとに 1 つの終端出力パスを選択してください。 |
| キュー実行 | 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 はビルダーの callable と出力パスを受け取ります。ジョブは実行時に安全でないパスを検証します。それでもアプリケーションコードでは、ディスパッチ前にテナントセーフなストレージルートを選択すべきです。
<?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 ビルダー | ドキュメントを非同期に構築します。 | callable は Laravel のキュー転送によってシリアライズ可能でなければなりません。 |
| 成功/失敗のコールバック | 生成後の通知またはクリーンアップ。 | コールバックは冪等に保ち、副作用を意識してください。 |
| オプションの Premium コントラクト | 電子請求書のエンベッダー、バリデーター、プロファイル、Schematron ランナー。 | オプションのパッケージがインストールされ、ライセンスされている環境でのみ解決してください。 |
開発ワークフロー
「開発ワークフロー」という見出しのセクション- 最初のドキュメントは、コントローラーまたは機能テストで同期的に構築します。
- レイアウトコードを
app/Pdf/Builders配下のビルダークラスに移動します。 - クエリと認可のロジックをアプリケーションサービスに移動します。
- ヘッダーとファイル名に関する
PdfResponseテストを追加します。 - 低速または大量の生成は
GeneratePdfJobに移動します。 - シリアライズされたコンテキスト、出力パスのポリシー、失敗処理に関するキューテストを追加します。
- 代表的な本番データでメモリとレンダリング時間を測定します。
| 失敗 | 処理すべき場所 | 推奨される対応 |
|---|---|---|
| 無効なリクエストまたは認可されていないドキュメント | コントローラーまたはポリシー。 | 通常のアプリケーションの認可レスポンスまたはバリデーションレスポンスを返します。 |
| フォントの欠落または無効な画像 | ビルダーテストとアプリケーションのロギング。 | リクエストまたはジョブを失敗させ、部分的な PDF を出力しないでください。 |
| 安全でない出力パス | アプリケーションのストレージサービスと GeneratePdfJob。 | ディスパッチ前に拒否し、多層防御としてワーカー側の検証も前提にします。 |
| 署名または TSA の失敗 | 署名サービスの境界。 | ドキュメントを未署名にしてよいかを判断します。規制対象のドキュメントでは、デフォルトでフェイルクローズとします。 |
| キューのタイムアウト | キューワーカーの構成と可観測性。 | ビルダーが決定論的で、出力パスを安全に上書きできる場合にのみ再試行してください。 |
安全なデフォルト
「安全なデフォルト」という見出しのセクション| 対象 | デフォルト | 上書きする場面 |
|---|---|---|
| キュー名 | pdf | 生成がユーザー向けジョブと競合する場合は、専用のキューを使用してください。 |
| ジョブのタイムアウト | 120 秒 | ドキュメントサイズとワーカー容量を測定した後でのみ増やしてください。 |
| レスポンスのファイル名 | document.pdf | サニタイズ済みの業務識別子を使用してください。 |
| フォントレジストリ | ウォームアップ後に共有され、ロックされます。 | ホットパスで使用するフォントには preload_fonts を追加してください。 |
| 画像レジストリ | 共有の上限付きキャッシュ。 | メモリが制約されたワーカーでは image_cache_mb を下げてください。 |
| ストリーミングレスポンスのチャンク分割 | 64 KB のチャンク。 | チャンクの境界に依存しないでください。これは出力上の詳細です。 |
テストチェックリスト
「テストチェックリスト」という見出しのセクション- コントローラーテストで
Content-Type、Content-Disposition、および防御用ヘッダーをアサートします。 - ビルダーテストは決定論的な DTO を使用し、データベースへクエリを発行しません。
- キューテストは、ビルダーが新しいドキュメントを受け取ることをアサートします。
- パステストでは、トラバーサル、ストリームラッパー、ヌルバイト、および
.pdf以外の拒否をカバーします。 - ワーカーテストは、本番と同じメモリ制限の下で代表的なドキュメントをレンダリングします。
- オプションの署名テストは、証明書の欠落、無効なパスワード、TSA の利用不可、設定済みの署名レベルをカバーします。