คู่มือสำหรับนักพัฒนา Laravel
ภาพรวมโดยย่อ
หัวข้อที่มีชื่อว่า “ภาพรวมโดยย่อ”แพ็กเกจ Laravel ทำให้ NextPDF สอดคล้องกับแนวทางปฏิบัติของ Laravel โดยไม่เปลี่ยนวงจรชีวิตของเอกสารในแกนหลัก คอนเทนเนอร์เป็นผู้ดูแลรีจิสทรีและแฟกทอรีที่ใช้ร่วมกัน เอกสาร PDF แต่ละชุดเป็นแบบใช้ครั้งเดียวแล้วทิ้ง ดังนั้นควรสร้าง ส่งคืน สตรีม หรือบันทึกเพียงครั้งเดียว
ใช้คู่มือนี้เมื่อออกแบบบริการของแอปพลิเคชัน งานคิว ขั้นตอนการตอบสนอง หรือความครอบคลุมของการทดสอบสำหรับ nextpdf/laravel
ขอบเขตของสถาปัตยกรรม
หัวข้อที่มีชื่อว่า “ขอบเขตของสถาปัตยกรรม”| เลเยอร์ | เป็นเจ้าของโดย | ความรับผิดชอบ | ไม่ควรใส่ที่นี่ |
|---|---|---|---|
| Controller | แอปพลิเคชัน | ตรวจสิทธิ์คำขอ เลือกตัวสร้างเอกสาร และส่งคืนการตอบสนอง | กฎเค้าโครง PDF ที่ใช้ร่วมกันข้ามหลายกรณีการใช้งาน |
| บริการของแอปพลิเคชัน | แอปพลิเคชัน | รวบรวมข้อมูลโดเมนและเรียกโค้ดสร้างเอกสาร | ตรรกะการบูตคอนเทนเนอร์หรือการกำหนดค่าแพ็กเกจ |
| ตัวสร้างเอกสาร | แอปพลิเคชัน | แปลงข้อมูลโดเมนเป็นการเรียกใช้เอกสารของ NextPDF | ออบเจ็กต์คำขอ ตรรกะการสืบค้นของ Eloquent หรือรายละเอียดการขนส่งคิว |
| การผสานรวมกับ Laravel | nextpdf/laravel | ผูกแฟกทอรี รีจิสทรี ตัวลงนาม ไคลเอนต์ TSA facade การตอบสนอง และงานคิว | เส้นทางที่เก็บข้อมูลเฉพาะธุรกิจหรือนโยบายผู้เช่า |
| เอนจินแกนหลัก | nextpdf/nextpdf | สร้าง PDF และทำให้เป็นอนุกรม | นโยบายการตอบสนอง คิว หรือระบบไฟล์ของ Laravel |
วงจรชีวิตขณะรันไทม์
หัวข้อที่มีชื่อว่า “วงจรชีวิตขณะรันไทม์”| ขั้นตอน | พฤติกรรม | การดำเนินการของนักพัฒนา |
|---|---|---|
| การลงทะเบียน Service provider | NextPdfServiceProvider::register() ลงทะเบียนรีจิสทรีที่ใช้ร่วมกัน แฟกทอรีเอกสาร การผูกเอกสาร ไคลเอนต์ HTTP ไคลเอนต์ผู้ออกการประทับเวลา (TSA) ตัวลงนาม และสัญญา e-invoice แบบเลือกใช้ได้ | เผยแพร่และตรวจสอบ config/nextpdf.php ก่อนนำขึ้นใช้งานจริง |
| การกำหนดเอกสาร | facade Pdf และการผูก PdfDocumentInterface กำหนดเอกสารใหม่ผ่าน DocumentFactoryInterface | กำหนดเอกสารหนึ่งครั้งต่อหนึ่งคำขอ คำสั่ง หรืองานคิว |
| การเขียนเอกสาร | โค้ดของแอปพลิเคชันเรียก API เอกสารในแกนหลักผ่าน facade หรือเอกสารที่ฉีดเข้ามา | เก็บการดึงข้อมูลโดเมนไว้นอกตัวสร้างเอกสาร |
| เอาต์พุตปลายทาง | PdfResponse ส่งเอาต์พุต HTTP หรือบันทึกเอกสารลงดิสก์ | เลือกเส้นทางเอาต์พุตปลายทางเพียงเส้นทางเดียวต่อเอกสารหนึ่งชุด |
| การประมวลผลในคิว | GeneratePdfJob สร้างเอกสารใหม่ใน worker และตรวจสอบเส้นทางเอาต์พุตซ้ำ | ส่งบริบทแบบสเกลาร์และทำให้คอลแบ็กเป็น idempotent |
โครงสร้างแอปพลิเคชันที่แนะนำ
หัวข้อที่มีชื่อว่า “โครงสร้างแอปพลิเคชันที่แนะนำ”| เส้นทาง | วัตถุประสงค์ |
|---|---|
app/Pdf/Builders/* | ตัวสร้างเอกสารแบบบริสุทธิ์ รับข้อมูลและส่งคืนเอกสารที่สมบูรณ์แล้ว |
app/Pdf/Data/* | ออบเจ็กต์ถ่ายโอนข้อมูล (DTO) ขนาดเล็กที่ส่งต่ออินพุตเอกสารซึ่งผ่านการอนุญาตแล้ว |
app/Services/* | การประสานงานของแอปพลิเคชัน การสืบค้น การส่งต่อการตรวจสิทธิ์ และการเลือกเส้นทางที่เก็บข้อมูล |
app/Jobs/* | ตัวห่อหุ้มแบบเลือกใช้ได้รอบ GeneratePdfJob เมื่อแอปพลิเคชันต้องการงานที่มีชื่อเฉพาะ |
tests/Feature/Pdf/* | การทดสอบการตอบสนอง HTTP การส่งงานเข้าคิว และการอนุญาต |
tests/Unit/Pdf/* | การทดสอบตัวสร้างด้วยอินพุตขนาดเล็กที่ให้ผลลัพธ์แน่นอน |
รักษาตัวสร้างให้เป็นอิสระจากออบเจ็กต์คำขอของ Laravel ควรเรียกใช้ตัวสร้างจาก controller คำสั่ง การทดสอบ หรือ queue worker ด้วยอินพุตเดียวกันได้
<?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 เป็นส่วนหนึ่งของตรรกะแอปพลิเคชัน ใช้ facade เฉพาะในขั้นตอน controller แบบสั้นซึ่งรูปแบบสแตติกอ่านง่ายกว่า
<?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'));ทำให้คอลแบ็กของคิวมีขนาดเล็ก ควรเขียนสถานะถาวรจาก job listener ของแอปพลิเคชันแทนการเก็บ closure ที่ซับซ้อนไว้ใน payload ของคิว
จุดต่อขยาย
หัวข้อที่มีชื่อว่า “จุดต่อขยาย”| จุดต่อขยาย | ใช้สำหรับ | ข้อจำกัด |
|---|---|---|
PdfDocumentInterface การผูก | แทนที่หรือตกแต่งการสร้างเอกสารสำหรับค่าเริ่มต้นระดับแอปพลิเคชัน | ต้องส่งคืนอินสแตนซ์เอกสารใหม่ |
DocumentFactoryInterface | สร้างเอกสารใหม่อย่างชัดเจนในบริการและการทดสอบ | อย่าแคชเอกสารที่ส่งคืน |
config/nextpdf.php | ค่าเริ่มต้น การตั้งค่าคิว การตั้งค่าตัวเรนเดอร์ Chrome ฮุกการลงนาม TSA แคช OCSP | ปฏิบัติต่อตัวแปรสภาพแวดล้อมเป็นการกำหนดค่าการปรับใช้ ไม่ใช่อินพุตของคำขอ |
GeneratePdfJob ตัวสร้าง | สร้างเอกสารแบบอะซิงโครนัส | callable ต้องทำให้เป็นอนุกรมได้ผ่านการขนส่งคิวของ Laravel |
| คอลแบ็กสำเร็จ/ล้มเหลว | การแจ้งเตือนหรือการล้างข้อมูลหลังการสร้าง | ทำให้คอลแบ็กเป็น idempotent และคำนึงถึงผลข้างเคียง |
| สัญญา Premium แบบเลือกใช้ได้ | ตัวฝัง ตัวตรวจสอบ โปรไฟล์ e-invoice และตัวรัน Schematron | กำหนดเฉพาะเมื่อมีการติดตั้งและได้รับสิทธิ์ใช้งานแพ็กเกจแบบเลือกใช้ได้แล้วเท่านั้น |
ขั้นตอนการพัฒนา
หัวข้อที่มีชื่อว่า “ขั้นตอนการพัฒนา”- สร้างเอกสารฉบับแรกแบบซิงโครนัสใน controller หรือการทดสอบฟีเจอร์
- ย้ายโค้ดเค้าโครงไปไว้ในคลาสตัวสร้างภายใต้
app/Pdf/Builders - ย้ายตรรกะการสืบค้นและการอนุญาตไปไว้ในบริการของแอปพลิเคชัน
- เพิ่มการทดสอบ
PdfResponseสำหรับส่วนหัวและชื่อไฟล์ - ย้ายการสร้างที่ช้าหรือมีปริมาณสูงไปยัง
GeneratePdfJob - เพิ่มการทดสอบคิวสำหรับบริบทที่ทำเป็นอนุกรม นโยบายเส้นทางเอาต์พุต และการจัดการความล้มเหลว
- วัดหน่วยความจำและเวลาเรนเดอร์ด้วยข้อมูลที่เป็นตัวแทนของการใช้งานจริง
การจัดการความล้มเหลว
หัวข้อที่มีชื่อว่า “การจัดการความล้มเหลว”| ความล้มเหลว | ควรจัดการที่ใด | การตอบสนองที่แนะนำ |
|---|---|---|
| คำขอที่ไม่ถูกต้องหรือเอกสารที่ไม่ได้รับอนุญาต | Controller หรือนโยบาย | ส่งคืนการตอบสนองด้านการอนุญาตหรือการตรวจสอบความถูกต้องตามปกติของแอปพลิเคชัน |
| ฟอนต์ที่หายไปหรือรูปภาพที่ไม่ถูกต้อง | การทดสอบตัวสร้างและการบันทึกล็อกของแอปพลิเคชัน | ให้คำขอหรืองานล้มเหลว อย่าส่งออก PDF ที่ไม่สมบูรณ์ |
| เส้นทางเอาต์พุตที่ไม่ปลอดภัย | บริการที่เก็บข้อมูลของแอปพลิเคชันและ GeneratePdfJob | ปฏิเสธก่อนส่งงานและใช้การตรวจสอบฝั่ง worker เป็นการป้องกันเชิงลึก |
| ความล้มเหลวของการลงนามหรือ TSA | ขอบเขตของบริการการลงนาม | พิจารณาว่าเอกสารสามารถไม่มีลายเซ็นได้หรือไม่ ค่าเริ่มต้นคือ fail closed สำหรับเอกสารที่อยู่ภายใต้การกำกับดูแล |
| คิวหมดเวลา | การกำหนดค่าและการสังเกตการณ์ของ queue worker | ลองใหม่เฉพาะเมื่อตัวสร้างให้ผลแน่นอนและเส้นทางเอาต์พุตเขียนทับได้อย่างปลอดภัย |
ค่าเริ่มต้นที่ปลอดภัย
หัวข้อที่มีชื่อว่า “ค่าเริ่มต้นที่ปลอดภัย”| ประเด็นที่เกี่ยวข้อง | ค่าเริ่มต้น | เมื่อใดควรแทนที่ |
|---|---|---|
| ชื่อคิว | pdf | ใช้คิวเฉพาะเมื่อการสร้างแย่งทรัพยากรจากงานที่ผู้ใช้กำลังรอ |
| งานหมดเวลา | 120 วินาที | เพิ่มเฉพาะหลังจากวัดขนาดเอกสารและความสามารถของ worker แล้ว |
| ชื่อไฟล์ของการตอบสนอง | document.pdf | ใช้ตัวระบุทางธุรกิจที่ผ่านการทำความสะอาดแล้ว |
| รีจิสทรีฟอนต์ | ใช้ร่วมกันและถูกล็อกหลังการอุ่นเครื่อง | เพิ่ม preload_fonts สำหรับฟอนต์ที่ใช้ในเส้นทางที่ถูกเรียกใช้บ่อย |
| รีจิสทรีรูปภาพ | แคชแบบมีขอบเขตที่ใช้ร่วมกัน | ลด image_cache_mb สำหรับ worker ที่มีหน่วยความจำจำกัด |
| การแบ่งส่วนของการตอบสนองแบบสตรีม | ส่วนขนาด 64 KB | อย่าพึ่งพาขอบเขตของส่วนข้อมูล เพราะเป็นรายละเอียดของเอาต์พุต |
รายการตรวจสอบการทดสอบ
หัวข้อที่มีชื่อว่า “รายการตรวจสอบการทดสอบ”- การทดสอบ controller ยืนยัน
Content-TypeContent-Dispositionและส่วนหัวเชิงป้องกัน - การทดสอบตัวสร้างใช้ DTO ที่ให้ผลลัพธ์แน่นอนและไม่สืบค้นฐานข้อมูล
- การทดสอบคิวยืนยันว่าตัวสร้างได้รับเอกสารใหม่
- การทดสอบเส้นทางครอบคลุมการเดินผ่านไดเรกทอรี stream-wrapper null-byte และการปฏิเสธไฟล์ที่ไม่ใช่
.pdf - การทดสอบ worker เรนเดอร์เอกสารที่เป็นตัวแทนภายใต้ขีดจำกัดหน่วยความจำเดียวกับการใช้งานจริง
- การทดสอบการลงนามแบบเลือกใช้ได้ครอบคลุมใบรับรองที่หายไป รหัสผ่านที่ไม่ถูกต้อง TSA ที่ไม่พร้อมใช้งาน และระดับลายเซ็นที่กำหนดค่าไว้