Panduan pengembang Laravel
Gambaran umum
Bagian berjudul “Gambaran umum”Paket Laravel menyelaraskan NextPDF dengan konvensi Laravel tanpa mengubah siklus hidup dokumen inti. Container memiliki registry dan factory bersama. Setiap dokumen PDF bersifat sekali pakai, sehingga Anda sebaiknya hanya membangun, mengembalikan, mengalirkan, atau menyimpannya satu kali.
Gunakan panduan ini saat merancang service aplikasi, queue job, alur respons, atau cakupan pengujian untuk nextpdf/laravel.
Batasan arsitektur
Bagian berjudul “Batasan arsitektur”| Lapisan | Dimiliki oleh | Tanggung jawab | Jangan tempatkan di sini |
|---|---|---|---|
| Controller | Aplikasi | Mengotorisasi permintaan, memilih document builder, dan mengembalikan respons. | Aturan tata letak PDF bersama yang digunakan di berbagai kasus penggunaan. |
| Service aplikasi | Aplikasi | Mengumpulkan data domain dan memanggil kode document builder. | Logika boot container atau konfigurasi paket. |
| Document builder | Aplikasi | Menerjemahkan data domain menjadi panggilan ke dokumen NextPDF. | Objek request, logika query Eloquent, atau detail transport queue. |
| Integrasi Laravel | nextpdf/laravel | Mengikat factory, registry, signer, klien TSA, facade, respons, dan queue job. | Jalur penyimpanan khusus bisnis atau kebijakan tenant. |
| Engine inti | nextpdf/nextpdf | Membangun dan menserialisasi PDF. | Kebijakan respons, queue, atau filesystem Laravel. |
Siklus hidup saat runtime
Bagian berjudul “Siklus hidup saat runtime”| Tahap | Perilaku | Tindakan pengembang |
|---|---|---|
| Registrasi service provider | NextPdfServiceProvider::register() mendaftarkan registry bersama, document factory, document binding, klien HTTP, klien time-stamping authority (TSA), signer, dan kontrak e-invoice opsional. | Publikasikan dan tinjau config/nextpdf.php sebelum produksi. |
| Resolusi dokumen | Facade Pdf dan binding PdfDocumentInterface meresolusi dokumen baru melalui DocumentFactoryInterface. | Resolusikan dokumen sekali saja per permintaan, perintah, atau queue job. |
| Penyusunan | Kode aplikasi memanggil API dokumen inti melalui facade atau dokumen yang di-inject. | Jaga agar ekstraksi data domain tetap berada di luar document builder. |
| Keluaran akhir | PdfResponse menghasilkan keluaran HTTP, atau dokumen disimpan ke disk. | Pilih satu jalur keluaran akhir per dokumen. |
| Eksekusi queue | GeneratePdfJob membangun ulang dokumen di dalam worker dan memvalidasi jalur keluaran sekali lagi. | Berikan konteks skalar dan jaga agar callback tetap idempoten. |
Struktur aplikasi yang direkomendasikan
Bagian berjudul “Struktur aplikasi yang direkomendasikan”| Jalur | Tujuan |
|---|---|
app/Pdf/Builders/* | Document builder murni yang menerima data dan mengembalikan dokumen yang sudah selesai. |
app/Pdf/Data/* | Data transfer object (DTO) ringkas yang membawa input dokumen yang sudah diotorisasi. |
app/Services/* | Orkestrasi aplikasi, query, delegasi otorisasi, dan pemilihan jalur penyimpanan. |
app/Jobs/* | Wrapper opsional di sekitar GeneratePdfJob saat aplikasi memerlukan job bernama. |
tests/Feature/Pdf/* | Pengujian respons HTTP, dispatch queue, dan otorisasi. |
tests/Unit/Pdf/* | Pengujian builder dengan input kecil yang deterministik. |
Pastikan builder tetap independen dari objek request Laravel. Anda sebaiknya dapat memanggil builder dari controller, perintah, pengujian, atau queue worker dengan input yang sama.
<?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; }}Pola respons sinkron
Bagian berjudul “Pola respons sinkron”Gunakan constructor injection saat alur PDF menjadi bagian dari logika aplikasi. Gunakan facade hanya untuk alur controller yang ringkas, ketika gaya statisnya lebih mudah dibaca.
<?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'); }}Helper respons mematerialisasi byte dokumen sebelum membangun respons Laravel. Helper tersebut adalah helper respons, bukan renderer latar belakang.
Pola queue
Bagian berjudul “Pola queue”GeneratePdfJob menerima builder callable dan satu jalur keluaran. Job memvalidasi jalur yang tidak aman saat dieksekusi. Kode aplikasi tetap sebaiknya memilih root penyimpanan yang aman untuk tenant sebelum dispatch.
<?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'));Jaga agar callback queue tetap kecil. Sebaiknya tulis status persisten dari listener job aplikasi, alih-alih menyimpan closure kompleks di dalam payload queue.
Titik ekstensi
Bagian berjudul “Titik ekstensi”| Titik ekstensi | Gunakan untuk | Batasan |
|---|---|---|
PdfDocumentInterface binding | Mengganti atau mendekorasi pembuatan dokumen untuk nilai standar di seluruh aplikasi. | Harus mengembalikan instance dokumen yang baru. |
DocumentFactoryInterface | Membuat dokumen baru secara eksplisit di dalam service dan pengujian. | Jangan cache dokumen yang dikembalikan. |
config/nextpdf.php | Nilai standar, pengaturan queue, pengaturan renderer Chrome, hook penandatanganan, cache TSA, OCSP. | Perlakukan variabel lingkungan sebagai konfigurasi deployment, bukan input permintaan. |
GeneratePdfJob builder | Membangun dokumen secara asinkron. | Callable harus dapat diserialisasi oleh transport queue Laravel. |
| Callback keberhasilan/kegagalan | Notifikasi atau pembersihan pascagenerasi. | Jaga agar callback tetap idempoten dan memperhitungkan efek samping. |
| Kontrak Premium opsional | Embedder e-invoice, validator, profil, dan runner Schematron. | Resolusikan hanya di tempat paket opsional terpasang dan berlisensi. |
Alur kerja pengembangan
Bagian berjudul “Alur kerja pengembangan”- Bangun dokumen pertama secara sinkron di dalam controller atau feature test.
- Pindahkan kode tata letak ke dalam kelas builder di bawah
app/Pdf/Builders. - Pindahkan logika query dan otorisasi ke dalam service aplikasi.
- Tambahkan pengujian
PdfResponseuntuk header dan nama berkas. - Pindahkan pembuatan yang lambat atau bervolume tinggi ke
GeneratePdfJob. - Tambahkan pengujian queue untuk konteks terserialisasi, kebijakan jalur keluaran, dan penanganan kegagalan.
- Ukur memori dan waktu render dengan data produksi yang representatif.
Penanganan kegagalan
Bagian berjudul “Penanganan kegagalan”| Kegagalan | Di mana harus ditangani | Respons yang direkomendasikan |
|---|---|---|
| Permintaan tidak valid atau dokumen tidak diotorisasi | Controller atau policy. | Kembalikan respons otorisasi atau validasi normal milik aplikasi. |
| Fon hilang atau gambar tidak valid | Pengujian builder dan pencatatan log aplikasi. | Gagalkan permintaan atau job; jangan keluarkan PDF parsial. |
| Jalur keluaran yang tidak aman | Service penyimpanan aplikasi dan GeneratePdfJob. | Tolak sebelum dispatch dan andalkan validasi di sisi worker sebagai pertahanan berlapis. |
| Kegagalan penandatanganan atau TSA | Batas service penandatanganan. | Putuskan apakah dokumen boleh tidak ditandatangani; gunakan default gagal-tertutup untuk dokumen yang tunduk pada regulasi. |
| Timeout queue | Konfigurasi queue worker dan observabilitas. | Coba ulang hanya saat builder bersifat deterministik dan jalur keluaran aman untuk ditimpa. |
Nilai standar yang aman
Bagian berjudul “Nilai standar yang aman”| Aspek | Nilai standar | Kapan menggantinya |
|---|---|---|
| Nama queue | pdf | Gunakan queue khusus saat pembuatan PDF bersaing dengan job yang menghadap pengguna. |
| Timeout job | 120 detik | Tingkatkan hanya setelah mengukur ukuran dokumen dan kapasitas worker. |
| Nama berkas respons | document.pdf | Gunakan identifier bisnis yang telah disanitasi. |
| Registry fon | Digunakan bersama dan dikunci setelah pemanasan. | Tambahkan preload_fonts untuk fon yang dipakai pada jalur sibuk. |
| Registry gambar | Cache terbatas yang digunakan bersama. | Turunkan image_cache_mb untuk worker dengan keterbatasan memori. |
| Pemecahan chunk pada respons yang dialirkan | Chunk 64 KB. | Jangan bergantung pada batas chunk; itu adalah detail keluaran. |
Daftar periksa pengujian
Bagian berjudul “Daftar periksa pengujian”- Pengujian controller memverifikasi
Content-Type,Content-Disposition, dan header defensif. - Pengujian builder menggunakan DTO deterministik dan tidak melakukan query ke basis data.
- Pengujian queue memverifikasi bahwa builder menerima dokumen yang baru.
- Pengujian jalur mencakup penolakan traversal, stream-wrapper, null-byte, dan non-
.pdf. - Pengujian worker merender dokumen yang representatif di bawah batas memori yang sama dengan produksi.
- Pengujian penandatanganan opsional mencakup sertifikat hilang, kata sandi tidak valid, TSA tidak tersedia, dan level tanda tangan yang dikonfigurasi.