Guía para desarrolladores de Cloudflare
De un vistazo
Sección titulada «De un vistazo»El paquete de Cloudflare traslada el renderizado al límite de un Worker. El renderizado en el Worker, el fallback local, la protección de la API y el archivado en R2 son capacidades distintas, cada una con su propio manejo de errores.
Usar esta guía al construir servicios de renderizado en el edge, endpoints de renderizado protegidos, flujos de archivado o rutas de fallback local en torno a nextpdf/cloudflare.
Límite arquitectónico
Sección titulada «Límite arquitectónico»| Capa | Propiedad de | Responsabilidad | No incluir aquí |
|---|---|---|---|
| Endpoint de la aplicación | Aplicación | Autorizar al solicitante, normalizar la solicitud de renderizado y aplicar la política de negocio. | Almacenar el token del Worker en el código. |
| Protección de la API | nextpdf/cloudflare y la aplicación | Decisiones sobre la clave de API, el tamaño del payload y el límite de tasa en el proceso. | Facturación, derechos del inquilino o aplicación de cuotas duraderas. |
| Renderer de Cloudflare | nextpdf/cloudflare | Validar el HTML y la URL del Worker, enviar el payload de renderizado y analizar la respuesta. | Renderizado de plantillas o consultas de dominio. |
| Worker | Despliegue de la aplicación | Ejecutar el Browser Rendering y devolver los bytes del PDF o un resultado estructurado. | Política de almacenamiento del lado de PHP. |
| Fallback local | Despliegue de la aplicación | Renderizar cuando el Worker no esté disponible. | Fallback silencioso que oculta las interrupciones operativas. |
| Archivado en R2 | nextpdf/cloudflare | Subir los PDF, construir las claves de objeto y crear URL firmadas. | Metadatos de negocio sensibles sin revisión. |
Ciclo de vida en tiempo de ejecución
Sección titulada «Ciclo de vida en tiempo de ejecución»| Etapa | Comportamiento | Acción del desarrollador |
|---|---|---|
| Creación de la configuración | Se cargan la URL del Worker, el token de API, los tiempos de espera, los límites de tamaño, el fallback y los pins. | Mantener los secretos en la configuración del despliegue. |
| Protección de la solicitud | El componente opcional ApiProtection valida la clave, el tamaño y el límite de tasa. | Ejecutarlo antes del trabajo costoso de renderizado. |
| Llamada al renderer | CloudflareHtmlRenderer valida el HTML y la URL del Worker, y luego envía JSON. | Manejar por separado la indisponibilidad del Worker y los fallos de renderizado. |
| Análisis de la respuesta | CloudflareResponseParser::parse() acepta una salida en PDF binario o en JSON estructurado. | Rechazar la salida inválida o que no sea PDF. |
| Fallback local | Un renderer local opcional se encarga del fallo del Worker. | Inyectar una fábrica de renderer local solo cuando el host admita ese modo. |
| Archivado en R2 | R2ArchiveManager almacena los bytes del PDF y crea URL firmadas. | Mantener los metadatos sin datos sensibles, salvo que se almacenen de forma intencional. |
Estructura de aplicación recomendada
Sección titulada «Estructura de aplicación recomendada»| Ruta | Propósito |
|---|---|
app/Pdf/Cloudflare/* | Wrapper de la aplicación en torno a CloudflareHtmlRenderer. |
app/Pdf/Workers/* | DTO de solicitud del Worker y política específica del endpoint. |
app/Pdf/Archive/* | Orquestación del archivado en R2 y decisiones de retención. |
app/Pdf/Fallback/* | LocalRendererFactoryInterface: implementación para cuando se permite el fallback. |
tests/Pdf/Cloudflare/* | Pruebas de Worker caído, token inválido, payload y archivado. |
Mantener separados el token de API de PHP y el token del Worker. La parte de PHP se autentica ante el Worker. El Worker debería autenticar las solicitudes entrantes antes de hacer el trabajo con el navegador.
<?php
use NextPDF\Cloudflare\ApiProtection;use NextPDF\Cloudflare\ApiProtectionConfig;use NextPDF\Cloudflare\ApiKeyValidator;
$protection = new ApiProtection( new ApiProtectionConfig(maxRequestsPerMinute: 30), new ApiKeyValidator([$expectedApiKey]),);
$result = $protection->checkRequest( clientId: $clientId, payloadSize: strlen($html), apiKey: $presentedApiKey,);
if (!$result->allowed) { return new JsonResponse(['error' => $result->denialReason], 429, $result->toHeaders());}Patrón del renderer
Sección titulada «Patrón del renderer»Construir el renderer con las dependencias PSR-18 y PSR-17 del framework. Mantener explícito el fallback local para que los operadores puedan identificar cuándo el sistema dejó de usar el Worker.
<?php
use NextPDF\Cloudflare\CloudflareHtmlRenderer;use NextPDF\Cloudflare\CloudflareRendererConfig;
$renderer = new CloudflareHtmlRenderer( config: CloudflareRendererConfig::fromArray([ 'worker_url' => getenv('NEXTPDF_CLOUDFLARE_WORKER_URL'), 'api_token' => getenv('NEXTPDF_CLOUDFLARE_API_TOKEN'), 'render_timeout' => 30, 'max_html_size' => 1_000_000, 'fallback_to_local' => false, ]), httpClient: $httpClient, requestFactory: $requestFactory, streamFactory: $streamFactory,);
$rendered = $renderer->render($html, widthPt: 595.28);Patrón de archivado en R2
Sección titulada «Patrón de archivado en R2»Archivar solo después de un renderizado exitoso y de la aprobación de la política. Tratar las URL públicas y las URL firmadas como decisiones distintas.
<?php
use NextPDF\Cloudflare\R2ArchiveManager;
$upload = $archive->upload( pdfData: $rendered->pdfData, filename: 'invoice-1234.pdf', metadata: [ 'document_type' => 'invoice', ],);
if ($upload->isValid()) { $temporaryUrl = $archive->generateSignedUrl($upload->key, 600);}No incluir nombres de clientes, direcciones de correo, totales de facturas ni identificadores regulados en los metadatos de objeto, a menos que la política de retención y acceso lo permita explícitamente.
Puntos de extensión
Sección titulada «Puntos de extensión»| Punto de extensión | Uso previsto | Restricción |
|---|---|---|
LocalRendererFactoryInterface | Fallback local a Artisan o a otro renderer. | Debe devolver un objeto que implemente LocalRendererInterface. |
ApiProtectionConfig | Política de clave de API, tamaño del payload y límite de tasa. | Los límites en memoria son por proceso. |
ApiKeyValidator | Validación de claves en tiempo constante y ayudantes para la rotación de claves. | Almacenar los secretos fuera del código fuente. |
R2ArchiveConfig | Bucket, credenciales, prefijo de ruta, endpoint y límites de tamaño. | Las credenciales nunca deben registrarse en los logs. |
PinnedCurlTransport | Aplicación de pins de IP y SPKI. | Requiere un entorno de ejecución con cURL y una fábrica de respuestas. |
CloudflareResponseParser | Análisis de la respuesta del Worker. | Rechaza los PDF inválidos o las respuestas de error. |
Flujo de desarrollo
Sección titulada «Flujo de desarrollo»- Construir primero una ruta de renderizado local.
- Añadir el renderizado en el Worker con un fixture de HTML pequeño y representativo.
- Habilitar la protección de la solicitud antes de exponer endpoints públicos.
- Añadir la subida a R2 solo después de que los flujos de renderizado y respuesta sean estables.
- Probar las rutas de Worker caído, token inválido, payload demasiado grande, límite de tasa y fallo de R2.
- Añadir logs que distingan el renderizado en el Worker, el renderizado de fallback, la subida al archivado y la creación de URL firmadas.
Manejo de errores
Sección titulada «Manejo de errores»| Error | Dónde debería manejarse | Respuesta recomendada |
|---|---|---|
| Clave de API ausente o inválida | Capa de protección de la API. | Rechazar antes de que empiece el trabajo de renderizado. |
| Payload demasiado grande | Protección de la API o validación del renderer. | Devolver un fallo de validación sin llamar al Worker. |
| URL del Worker no segura | Política de seguridad del renderer. | Hacer que la configuración o la solicitud fallen antes de la E/S de red. |
| Worker no disponible | Límite del renderer. | Usar el fallback explícito solo cuando esté permitido; de lo contrario, fallar de forma visible. |
| Fallo en la subida a R2 | Límite del archivado. | Devolver la respuesta del PDF si el archivado es opcional; fallar si la política exige el archivado. |
| Fallo en la rotación de pins | Despliegue y operaciones. | Rotar con pins de respaldo y un plan de rollback. |
Valores predeterminados seguros
Sección titulada «Valores predeterminados seguros»| Asunto | Predeterminado | Cuándo cambiarlo |
|---|---|---|
| Fallback | Habilitado por la configuración predeterminada. | Desactivarlo cuando el renderizado local violaría el aislamiento del despliegue. |
| Tamaño máximo del HTML | 5,000,000 bytes. | Reducirlo para endpoints públicos. |
| TTL de la URL firmada | 3600 segundos. | Acortarlo para PDF sensibles. |
| Conjuntos de pins | Vacío. | Añadir pins solo con un plan de rotación y pins de respaldo. |
| Requisito de clave de API | Habilitado por la configuración de protección predeterminada. | Desactivarlo solo para llamadas internas privadas y ya autenticadas. |
Lista de comprobación de pruebas
Sección titulada «Lista de comprobación de pruebas»- Las pruebas del renderer cubren HTML válido, HTML demasiado grande, URL del Worker inválida y respuesta de error del Worker.
- Las pruebas de protección de la API cubren clave ausente, clave inválida, payload demasiado grande y límite de tasa superado.
- Las pruebas de R2 cubren la subida exitosa, un intento de subida demasiado grande, el estado HTTP fallido, el bucket inválido y la generación de URL firmadas.
- Las pruebas de fallback verifican que la ruta del renderer local sea explícita y observable.
- Las pruebas de transporte cubren las IP fijadas, los pins de clave pública, el tiempo de espera y las redirecciones desactivadas por política.
- Las pruebas de observabilidad verifican eventos de log distintos para el renderizado, el fallback, el archivado y la creación de URL firmadas.