Руководство разработчика для Cloudflare
Пакет Cloudflare переносит отрисовку PDF на границу Worker. Рассматривайте отрисовку в Worker, локальный запасной вариант, защиту API и архив R2 как отдельные возможности, у каждой из которых своя обработка сбоев.
Используйте это руководство, когда создаёте сервисы отрисовки на границе сети, защищённые конечные точки отрисовки, процессы архивирования или локальные запасные пути с nextpdf/cloudflare.
Граница архитектуры
Заголовок раздела «Граница архитектуры»| Слой | Кому принадлежит | Ответственность | Не размещайте здесь |
|---|---|---|---|
| Конечная точка приложения | Приложение | Авторизуйте вызывающую сторону, нормализуйте запрос на отрисовку и применяйте бизнес-политику. | Токены Worker, хранящиеся в коде. |
| Защита API | nextpdf/cloudflare и приложение | Проверяйте ключ API и размер полезной нагрузки, принимайте решения об ограничении частоты запросов в рамках процесса. | Биллинг, права арендатора или надёжное применение квот. |
| Отрисовщик Cloudflare | nextpdf/cloudflare | Проверяйте HTML и URL Worker, отправляйте полезную нагрузку для отрисовки и разбирайте ответ. | Отрисовка шаблонов или предметные запросы. |
| Worker (воркер) | развёртывание приложения | Запустите Browser Rendering и верните байты PDF или структурированный результат. | Политика хранения на стороне PHP. |
| Локальный запасной вариант | развёртывание приложения | Отрисовка, когда Worker недоступен. | Тихий запасной вариант, скрывающий эксплуатационные сбои. |
| Архив R2 | nextpdf/cloudflare | Загружайте файлы PDF, формируйте ключи объектов и создавайте подписанные URL. | Конфиденциальные бизнес-метаданные без проверки. |
Жизненный цикл выполнения
Заголовок раздела «Жизненный цикл выполнения»| Этап | Поведение | Действие разработчика |
|---|---|---|
| Создание конфигурации | Загружает URL Worker, токен API, тайм-ауты, ограничения размера, запасной вариант и пины. | Храните секреты в конфигурации развёртывания. |
| Защита запросов | Необязательный ApiProtection проверяет ключ, размер и ограничение частоты. | Запускайте его до затратной работы по отрисовке. |
| Вызов отрисовщика | CloudflareHtmlRenderer проверяет HTML и URL Worker, затем отправляет JSON. | Обрабатывайте недоступность Worker и сбои отрисовки по отдельности. |
| Разбор ответа | CloudflareResponseParser::parse() принимает двоичный вывод PDF или структурированный вывод JSON. | Отклоняйте недопустимый вывод или вывод не в формате PDF. |
| Локальный запасной вариант | Необязательный локальный отрисовщик обрабатывает сбой Worker. | Внедряйте фабрику локального отрисовщика только тогда, когда хост её поддерживает. |
| Архив R2 | R2ArchiveManager хранит байты PDF и создаёт подписанные URL. | Сохраняйте метаданные неконфиденциальными, если вы не сохраняете их намеренно. |
Рекомендуемая структура приложения
Заголовок раздела «Рекомендуемая структура приложения»| Путь | Назначение |
|---|---|
app/Pdf/Cloudflare/* | Обёртка приложения для CloudflareHtmlRenderer. |
app/Pdf/Workers/* | Объекты передачи данных (DTO) запросов Worker и политика для конкретных конечных точек. |
app/Pdf/Archive/* | Оркестрация архива R2 и решения о сроках хранения. |
app/Pdf/Fallback/* | LocalRendererFactoryInterface — реализация для разрешённого запасного варианта. |
tests/Pdf/Cloudflare/* | Тесты на недоступность Worker, недействительный токен, полезную нагрузку и архив. |
Храните токен API для PHP отдельно от токена Worker. PHP аутентифицируется перед Worker. Worker должен аутентифицировать входящие запросы до запуска браузера.
<?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());}Шаблон отрисовщика
Заголовок раздела «Шаблон отрисовщика»Создайте отрисовщик с PSR-зависимостями из вашего фреймворка, включая PSR-18 и PSR-17. Делайте локальный запасной вариант явным, чтобы операторы видели, когда система перестаёт использовать 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);Шаблон архива R2
Заголовок раздела «Шаблон архива R2»Архивируйте только после успешной отрисовки и одобрения результата политикой. Рассматривайте публичные URL и подписанные URL как разные решения.
<?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);}Не размещайте имена клиентов, адреса электронной почты, итоговые суммы счетов или регулируемые идентификаторы в метаданных объекта, если политика хранения и доступа явно этого не разрешает.
Точки расширения
Заголовок раздела «Точки расширения»| Точка расширения | Используйте для | Ограничение |
|---|---|---|
LocalRendererFactoryInterface | Локальный запасной вариант через Artisan или другой отрисовщик. | Должен возвращать объект, который реализует LocalRendererInterface. |
ApiProtectionConfig | Ключ API, размер полезной нагрузки и политика ограничения частоты. | Ограничения в памяти применяются для каждого процесса. |
ApiKeyValidator | Помощники для проверки ключей с постоянным временем выполнения и ротации ключей. | Храните секреты вне исходного кода. |
R2ArchiveConfig | Бакет, учётные данные, префикс пути, конечная точка и ограничения размера. | Учётные данные никогда не должны записываться в журнал. |
PinnedCurlTransport | Применение IP-пинов и пинов SPKI. | Требует среды выполнения с поддержкой cURL и фабрики ответов. |
CloudflareResponseParser | Разбор ответа Worker. | Отклоняет недопустимый вывод PDF или ответы с ошибкой. |
Процесс разработки
Заголовок раздела «Процесс разработки»- Сначала создайте локальный путь отрисовки.
- Добавьте отрисовку в Worker с небольшим репрезентативным фикстурным HTML.
- Включите защиту запросов до открытия публичных конечных точек.
- Добавляйте загрузку в R2 только после стабилизации потоков отрисовки и ответа.
- Протестируйте пути с недоступным Worker, недействительным токеном, слишком большой полезной нагрузкой, ограничением частоты и сбоем R2.
- Добавьте журналы, различающие отрисовку в Worker, отрисовку через запасной вариант, загрузку в архив и создание подписанного URL.
Обработка сбоев
Заголовок раздела «Обработка сбоев»| Сбой | Где он должен обрабатываться | Рекомендуемая реакция |
|---|---|---|
| Отсутствующий или недействительный ключ API | Слой защиты API. | Отклоните запрос до начала работы по отрисовке. |
| Слишком большая полезная нагрузка | Защита API или проверка отрисовщика. | Верните ошибку проверки без вызова Worker. |
| Небезопасный URL Worker | Политика безопасности отрисовщика. | Отклоните конфигурацию или запрос до сетевого ввода-вывода input/output (I/O). |
| Worker недоступен | Граница отрисовщика. | Используйте явный запасной вариант только когда это разрешено; в противном случае дайте сбою проявиться. |
| Сбой загрузки в R2 | Граница архива. | Верните ответ PDF, если архивирование необязательно; дайте сбой, если архивирование требуется политикой. |
| Сбой ротации пинов | развёртывание и эксплуатация. | Выполняйте ротацию с резервными пинами и планом отката. |
Безопасные значения по умолчанию
Заголовок раздела «Безопасные значения по умолчанию»| Аспект | По умолчанию | Когда переопределять |
|---|---|---|
| Запасной вариант | Включён значением конфигурации по умолчанию. | Отключите, когда локальная отрисовка нарушила бы изоляцию развёртывания. |
| Максимальный размер HTML | 5,000,000 байт. | Снизьте для публичных конечных точек. |
| Срок жизни (TTL) подписанного URL | 3600 секунд. | Сократите для конфиденциальных PDF. |
| Наборы пинов | Пусто. | Добавляйте пины только с планом ротации и резервными пинами. |
| Требование ключа API | Включено значением конфигурации защиты по умолчанию. | Отключайте только для приватных, уже аутентифицированных внутренних вызовов. |
Контрольный список тестирования
Заголовок раздела «Контрольный список тестирования»- Тесты отрисовщика охватывают допустимый HTML, слишком большой HTML, недействительный URL Worker и ответ Worker с ошибкой.
- Тесты защиты API охватывают отсутствующий ключ, недействительный ключ, слишком большую полезную нагрузку и превышенное ограничение частоты.
- Тесты R2 охватывают успешную загрузку, слишком большую загрузку, неуспешный статус протокола передачи гипертекста (HTTP), недействительный бакет и генерацию подписанного URL.
- Тесты запасного варианта проверяют, что путь локального отрисовщика явный и наблюдаемый.
- Тесты транспорта охватывают закреплённые IP, пины открытых ключей, тайм-аут и отключённые политикой перенаправления.
- Тесты наблюдаемости подтверждают наличие отдельных событий журнала для отрисовки, запасного варианта, архивирования и создания подписанного URL.