Guide du développeur Laravel
Le package Laravel adapte NextPDF aux conventions de Laravel sans modifier le cycle de vie du document du cœur. Le conteneur détient les registres et les fabriques partagés. Chaque document PDF est à usage unique et doit être construit, retourné, diffusé ou enregistré une seule fois.
Utilise ce guide lorsque tu conçois des services applicatifs, des jobs de file d’attente, des flux de réponse ou la couverture de tests autour de nextpdf/laravel.
Frontière architecturale
Section intitulée « Frontière architecturale »| Couche | Détenu par | Responsabilité | À ne pas mettre ici |
|---|---|---|---|
| Contrôleur | Application | Autoriser la requête, choisir un constructeur de document et retourner une réponse. | Les règles de mise en page PDF communes aux cas d’usage. |
| Service applicatif | Application | Collecter les données du domaine et appeler le code de construction du document. | La logique d’amorçage du conteneur ou la configuration du package. |
| Constructeur de document | Application | Traduire les données du domaine en appels de document NextPDF. | Les objets de requête, la logique de requête Eloquent ou les détails du transport de file d’attente. |
| Intégration Laravel | nextpdf/laravel | Lier les fabriques, les registres, le signataire, le client TSA, la façade, les réponses et le job de file d’attente. | Les chemins de stockage propres au métier ou la politique de tenant. |
| Moteur du cœur | nextpdf/nextpdf | Construire et sérialiser le PDF. | La réponse Laravel, la file d’attente ou la politique du système de fichiers. |
Cycle de vie à l’exécution
Section intitulée « Cycle de vie à l’exécution »| Étape | Comportement | Action du développeur |
|---|---|---|
| Enregistrement du service provider | NextPdfServiceProvider::register() enregistre les registres partagés, la fabrique de documents, la liaison du document, le client HTTP, le client TSA, le signataire et les contrats e-invoice optionnels. | Publie config/nextpdf.php et passe-le en revue avant la production. |
| Résolution du document | La façade Pdf et la liaison PdfDocumentInterface résolvent un document neuf via DocumentFactoryInterface. | Résous un document une seule fois par requête, commande ou job mis en file d’attente. |
| Rédaction | Le code applicatif appelle les API de document du cœur via la façade ou le document injecté. | Garde l’extraction des données du domaine hors du constructeur de document. |
| Sortie terminale | PdfResponse émet la sortie HTTP, ou le document est enregistré sur le disque. | Choisis un seul chemin de sortie terminale pour chaque document. |
| Exécution en file d’attente | GeneratePdfJob reconstruit le document dans le worker et valide à nouveau le chemin de sortie. | Passe un contexte scalaire et garde les callbacks idempotents. |
Structure applicative recommandée
Section intitulée « Structure applicative recommandée »| Chemin | Objectif |
|---|---|
app/Pdf/Builders/* | Des constructeurs de documents purs. Ils reçoivent des données et retournent un document terminé. |
app/Pdf/Data/* | De petits DTO qui transportent une entrée de document déjà autorisée. |
app/Services/* | L’orchestration applicative, les requêtes, le relais d’autorisation et la sélection du chemin de stockage. |
app/Jobs/* | Des wrappers optionnels autour de GeneratePdfJob lorsque l’application a besoin de jobs nommés. |
tests/Feature/Pdf/* | Les tests de réponse HTTP, de dispatch en file d’attente et d’autorisation. |
tests/Unit/Pdf/* | Les tests de constructeur avec une entrée courte et déterministe. |
Garde les constructeurs indépendants des objets de requête Laravel. Un constructeur doit pouvoir être appelé depuis un contrôleur, une commande, un test et un worker de file d’attente avec la même entrée.
<?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; }}Modèle de réponse synchrone
Section intitulée « Modèle de réponse synchrone »Utilise l’injection par constructeur lorsque le flux PDF fait partie de la logique applicative. N’utilise la façade que pour les flux de contrôleur courts où le style statique améliore la lisibilité.
<?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'); }}Les helpers de réponse matérialisent les octets du document avant de construire la réponse Laravel. Ce sont des helpers de réponse, pas des moteurs de rendu d’arrière-plan.
Modèle de file d’attente
Section intitulée « Modèle de file d’attente »GeneratePdfJob accepte un callable de construction et un chemin de sortie. Le job valide les chemins dangereux au moment de l’exécution. Le code applicatif doit malgré tout choisir une racine de stockage sûre pour le tenant avant le 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'));Les callbacks de file d’attente doivent rester courts. Préfère écrire un état durable depuis un listener de job applicatif plutôt que de stocker des closures complexes dans la charge utile de la file d’attente.
Points d’extension
Section intitulée « Points d’extension »| Point d’extension | À utiliser pour | Contrainte |
|---|---|---|
PdfDocumentInterface (liaison) | Remplacer ou décorer la création du document pour des valeurs par défaut à l’échelle de l’application. | Doit retourner une instance de document neuve. |
DocumentFactoryInterface | Créer explicitement un document neuf dans les services et les tests. | Ne mets pas en cache les documents retournés. |
config/nextpdf.php | Les valeurs par défaut, les réglages de file d’attente, les réglages du moteur de rendu Chrome, les hooks de signature, le cache TSA et OCSP. | Traite les variables d’environnement comme de la configuration de déploiement, pas comme une entrée de requête. |
GeneratePdfJob (constructeur) | Construire des documents de façon asynchrone. | Le callable doit être sérialisable par le transport de file d’attente Laravel. |
| Les callbacks de succès et d’échec | La notification ou le nettoyage après génération. | Garde les callbacks idempotents et maîtrise leurs effets de bord. |
| Les contrats Premium optionnels | L’intégrateur d’e-invoice, le validateur, le profil et l’exécuteur Schematron. | Ne les résous que là où le package optionnel est installé et licencié. |
Flux de travail de développement
Section intitulée « Flux de travail de développement »- Construis le premier document de façon synchrone dans un contrôleur ou un test fonctionnel.
- Déplace le code de mise en page dans une classe de constructeur sous
app/Pdf/Builders. - Déplace la logique de requête et d’autorisation dans un service applicatif.
- Ajoute des tests
PdfResponsepour les en-têtes et les noms de fichiers. - Déplace la génération lente ou à fort volume vers
GeneratePdfJob. - Ajoute des tests de file d’attente pour le contexte sérialisé, la politique de chemin de sortie et la gestion des échecs.
- Mesure la mémoire et le temps de rendu avec des données de production représentatives.
Gestion des échecs
Section intitulée « Gestion des échecs »| Échec | Où il doit être traité | Réponse recommandée |
|---|---|---|
| Requête invalide ou document non autorisé | Contrôleur ou politique. | Retourne la réponse d’autorisation ou de validation applicative habituelle. |
| Police manquante ou image invalide | Test de constructeur et journalisation applicative. | Fais échouer la requête ou le job ; n’émets pas de PDF partiels. |
| Chemin de sortie dangereux | Le service de stockage applicatif et GeneratePdfJob. | Rejette avant le dispatch et appuie-toi sur la validation côté worker comme défense en profondeur. |
| Échec de signature ou de TSA | La frontière du service de signature. | Décide si le document peut rester non signé ; par défaut, échoue en mode fermé pour les documents réglementés. |
| Délai d’attente de la file d’attente dépassé | La configuration et l’observabilité du worker de file d’attente. | Ne réessaie que lorsque le constructeur est déterministe et que le chemin de sortie peut être écrasé sans risque. |
Valeurs par défaut sûres
Section intitulée « Valeurs par défaut sûres »| Préoccupation | Valeur par défaut | Quand la remplacer |
|---|---|---|
| Nom de la file d’attente | pdf | Utilise une file d’attente dédiée quand la génération entre en concurrence avec les jobs destinés aux utilisateurs. |
| Délai d’attente du job | 120 secondes | Ne l’augmente qu’après avoir mesuré la taille du document et la capacité du worker. |
| Nom de fichier de la réponse | document.pdf | Utilise des identifiants métier assainis. |
| Registre de polices | Partagé et verrouillé après le préchauffage. | Ajoute preload_fonts pour les polices utilisées sur les chemins critiques. |
| Registre d’images | Cache partagé borné. | Abaisse image_cache_mb pour les workers à mémoire limitée. |
| Découpage de la réponse diffusée en chunks | Chunks de 64 Ko. | Ne dépends pas des frontières de chunk ; ce sont un détail de sortie. |
Liste de contrôle des tests
Section intitulée « Liste de contrôle des tests »- Les tests de contrôleur vérifient
Content-Type,Content-Dispositionet les en-têtes défensifs. - Les tests de constructeur utilisent des DTO déterministes et n’interrogent pas la base de données.
- Les tests de file d’attente vérifient que le constructeur reçoit un document neuf.
- Les tests de chemin couvrent la traversée, le wrapper de flux, l’octet nul et le rejet des fichiers non-
.pdf. - Les tests de worker rendent des documents représentatifs sous la même limite de mémoire qu’en production.
- Les tests de signature optionnels couvrent le certificat manquant, le mot de passe invalide, le TSA indisponible et le niveau de signature configuré.