Contracts: 41개의 공개 인터페이스(SPI)
한눈에 보기
섹션 제목: “한눈에 보기”NextPDF\Contracts는 공개 서비스 제공자 인터페이스(SPI)입니다. src/Contracts/ 아래에 있는 41개의 인터페이스와 열거형으로 구성되며, 명시적인 @stability 태그와 하위 호환성 약속을 포함합니다. 확장 패키지, 프레임워크 브리지, Pro 및 Enterprise 에디션은 구체 클래스 대신 이러한 타입을 대상으로 코드를 작성합니다.
composer require nextpdf/core:^3개념 개요
섹션 제목: “개념 개요”엔진은 두 가지 표면을 분리합니다. src/Core/, src/Html/, src/Writer/ 아래의 구체 클래스에는 호환성 약속이 적용되지 않습니다. 이러한 클래스는 마이너 버전 사이에서 자유롭게 변경될 수 있습니다. Contracts 네임스페이스는 그 반대입니다. 선언한 안정성 등급에 따라 시그니처가 고정된, 선별된 타입 집합입니다. 엔진 외부의 모든 요소는 이 네임스페이스에 의존하며, 그보다 더 깊은 구현에는 의존하지 않습니다. 여기에는 Laravel, Symfony, CodeIgniter 브리지, compat-tcpdf 심(shim), NextPDF Server, Pro 및 Enterprise 에디션이 포함됩니다.
각 계약은 자체 PHPDoc에서 네 가지 등급 중 하나를 선언합니다. stable 계약은 마이너 또는 패치 릴리스에서 호환성을 깨는 변경을 허용하지 않습니다. 새 메서드는 기본 구현이 함께 제공될 때만 추가됩니다. experimental 계약은 사용 중단 안내와 함께 마이너 릴리스에서 변경될 수 있습니다. deprecated 계약은 대체 대상을 명시합니다. 일부는 계약 전용이며, StreamingWriterInterface와 CursorInterface 등이 이에 해당합니다. 해당 타입은 공개되어 있고 고정되어 있지만, 아직 프로덕션 구현은 제공되지 않습니다.
권위 있는 등급 목록은 docs/extension-points.json입니다(매니페스트 버전 3.0.0, Contracts와 Event 전반에 걸쳐 공개된 지점 67개). 기계로 검증 가능한 테스트인 tests/Unit/Contracts/StabilityContractTest.php는 해당 매니페스트를 읽습니다. 이 테스트는 다섯 가지 조건에서 빌드를 실패시킵니다. 첫째는 목록에는 있지만 실제로 누락된 타입입니다. 둘째는 리플렉션으로 확인한 종류가 매니페스트와 일치하지 않는 경우입니다. 셋째는 매니페스트와 맞지 않는 @stability PHPDoc 태그입니다. 넷째는 src/Contracts/ 아래에 있으나 매니페스트에는 없는 계약입니다. 다섯째는 매니페스트에 포함된 @internal 타입입니다. 계약 표면의 변경은 감지되지 않은 채 빠져나갈 수 없습니다.
계약은 아홉 개의 도메인으로 나뉩니다. 각 도메인에는 전용 페이지가 있습니다: 문서 구성, 서명, 바코드 인코딩, 타이포그래피, 보안 정책, 추출, 관찰 가능성, 스트리밍. 이 구분은 통합 담당자가 엔진을 도입하는 방식을 반영합니다. PDF를 생성하려면 document 계약에 의존합니다. 서명을 추가하려면 signing 계약에 의존합니다. 신뢰할 수 없는 HTML을 제약하려면 security-policy 계약에 의존합니다.
선택적 구현을 해석하는 방식은 엔진 전반에서 하나의 패턴을 따릅니다. Core는 class_exists()로 구체 클래스를 확인한 뒤 이를 계약으로 캐스팅합니다. LtvManagerInterface와 PdfAManagerInterface는 이 방식으로 Pro 구현을 해석합니다. 따라서 Core는 Apache-2.0 라이선스를 유지하며 상용 코드에 대한 강한 의존성을 갖지 않습니다.
API 표면
섹션 제목: “API 표면”| 계약 | 종류 | 안정성 | 도입 버전 | 도메인 |
|---|---|---|---|---|
PdfDocumentInterface | interface | stable(안정) | 1.0.0 | document(문서) |
DocumentFactoryInterface | interface | stable(안정) | 1.7.0 | document(문서) |
ResettableService | interface | stable(안정) | 1.7.0 | document(문서) |
OutputDestination | enum | stable(안정) | 1.0.0 | document(문서) |
Orientation | enum | stable(안정) | 1.0.0 | document(문서) |
Alignment | enum | stable(안정) | 1.0.0 | document(문서) |
SignerInterface | interface | stable(안정) | 1.0.0 | signing(서명) |
HsmSignerInterface | interface | stable(안정) | 1.0.0 | signing(서명) |
DeferredSignerInterface | interface | experimental(실험적) | 3.0.0 | signing(서명) |
TimestampProviderInterface | interface | experimental(실험적) | 3.0.0 | signing(서명) |
LtvManagerInterface | interface | stable(안정) | 1.10.0 | signing(서명) |
CryptoPolicyInterface | interface | stable(안정) | 1.9.0 | signing(서명) |
Barcode1DEncoderInterface | interface | stable(안정) | 1.0.0 | barcode(바코드) |
Barcode2DEncoderInterface | interface | stable(안정) | 1.0.0 | barcode(바코드) |
BarcodeEncoderInterface | interface | stable(안정) | 3.0.0 | barcode(바코드) |
Gs1DataParserInterface | interface | stable(안정) | 1.0.0 | barcode(바코드) |
FontRegistryInterface | interface | stable(안정) | 1.7.0 | typography(타이포그래피) |
TextPreprocessorInterface | interface | stable(안정) | 1.9.0 | typography(타이포그래피) |
HtmlSecurityPolicyInterface | interface | stable(안정) | 3.1.0 | security-policy(보안 정책) |
ExternalResourcePolicyInterface | interface | stable(안정) | 4.0.0 | security-policy(보안 정책) |
InspectorInterface | interface | experimental(실험적) | 2.2.0 | extraction(추출) |
EmbeddingServiceInterface | interface | experimental(실험적) | 2.1.0 | extraction(추출) |
VectorIndexInterface | interface | experimental(실험적) | 2.1.0 | extraction(추출) |
JobNotificationInterface | interface | experimental(실험적) | 2.2.0 | observability(관찰 가능성) |
SpectrumInterface | interface | experimental(실험적) | 2.1.0 | observability(관찰 가능성) |
StreamingWriterInterface | interface | experimental(실험적) | 3.1.0 | streaming(스트리밍) |
CursorInterface | interface | experimental(실험적) | 3.1.0 | streaming(스트리밍) |
이 표는 주요 계약을 나열합니다. 나머지 타입인 값 객체 DTO(TextSegment, TextPreprocessResult), EInvoice 하위 네임스페이스, 동작 열거형(DegradationPolicy, UnderlineStyle), 임포트 계약(ImportedFormObjectInterface, EmbeddedPdfObjectInterface, ChromeRenderResultInterface)은 참고 항목 아래의 도메인 페이지에 문서화되어 있습니다. 전체 기계 판독 가능 목록은 docs/extension-points.json이며, .ai/contracts-map.md에 미러링되어 있습니다.
코드 예제 — 빠른 시작
섹션 제목: “코드 예제 — 빠른 시작”<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();$doc->setTitle('Hello World');$doc->addPage();$doc->setFont('helvetica', '', 24);$doc->cell(0, 15, 'Hello, NextPDF!', newLine: true);$doc->save(__DIR__ . '/output/01-hello-world.pdf');Document::createStandalone()는 PdfDocumentInterface를 충족하는 구체 Document를 반환합니다. 엔진 내부를 교체 가능하게 유지하려면 자체 서비스에서 해당 인터페이스를 타입 힌트로 사용하세요.
코드 예제 — 프로덕션
섹션 제목: “코드 예제 — 프로덕션”<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Core\DocumentFactory;use NextPDF\Core\PdfFactory;use NextPDF\Graphics\ImageRegistry;use NextPDF\Typography\FontRegistry;
// Created once at process boot in a RoadRunner/Swoole/Octane worker.$fontRegistry = new FontRegistry();$imageRegistry = new ImageRegistry(maxCacheBytes: 50 * 1024 * 1024);$documentFactory = new DocumentFactory($fontRegistry, $imageRegistry);
$factory = PdfFactory::new() ->withCompress(true) ->withDocumentFactory($documentFactory);
for ($request = 1; $request <= 3; $request++) { $doc = $factory->create(); $doc->setTitle("Worker Request #{$request}"); $doc->addPage(); $doc->setFont('helvetica', 'B', 16); $doc->cell(0, 12, "Worker Request #{$request}", newLine: true); $doc->save(__DIR__ . "/output/14-worker-request-{$request}.pdf");}DocumentFactory는 DocumentFactoryInterface를 구현합니다. 이 팩토리는 프로세스 수명 동안 유지되는 FontRegistryInterface와 ImageRegistryInterface 싱글턴을 보유하며 이를 각 일회성 Document에 주입하므로, 워커는 수천 건의 요청에 걸쳐 각 글꼴을 한 번만 파싱합니다.
예외 사례 및 주의점
섹션 제목: “예외 사례 및 주의점”- 계약 전용 타입은 컴파일되지만 런타임 백엔드가 없습니다.
new를StreamingWriterInterface또는CursorInterface에 적용하는 것은 아직 어떤 클래스도 이를 구현하지 않으므로 성공할 수 없습니다. 이들을 전방 선언된 API로 취급하세요. - 단일 타입에 대해서는
@stabilityPHPDoc 태그가 공식 기준입니다.docs/extension-points.json은 타입 집합에 대한 공식 기준입니다. 둘이 일치하지 않으면StabilityContractTest가 실패합니다. 한쪽을 편집하여 불일치를 숨기지 마세요. experimental은 실제로 불안정하다는 의미가 아니라 호환성 약속이 더 약하다는 의미입니다. 각 계약에 의존하기 전에.ai/contracts-map.md의bc_promise필드를 읽어 보세요.- 다른 패키지가 기술적으로 참조할 수 있더라도
@internal클래스는 절대 계약이 아닙니다. 안정성 테스트는 매니페스트에 나타나는@internal타입을 거부합니다. - 메서드를
stable인터페이스에 추가하는 것은, 그 메서드가 기본 구현과 함께 제공되지 않는 한 구현자에게 호환성을 깨는 변경입니다. 엔진은 기존 인터페이스를 확장하는 것이 아니라 새 인터페이스를 통해 기능을 추가합니다.
코드를 Contracts를 대상으로 작성해도 측정 가능한 런타임 비용이 추가되지 않습니다. 인터페이스 타입 힌트는 호출할 때마다가 아니라 링크 시점에 해석됩니다. performance_budget은 이 페이지의 워커 예제에 대해 문서 3개 기준으로 벽시계 시간 1500ms, 피크 64MB입니다. 첫 요청의 글꼴 파싱이 그 예산의 대부분을 차지합니다. 이후 요청은 레지스트리 캐시를 재사용하여 계약 때문에 발생하는 작업이 한 자릿수 밀리초로 줄어듭니다. 비용 모델은 계약 디스패치당 O(1)이며, 실제 작업은 각 도메인 페이지에 문서화된 구체 구현에 있습니다.
보안 참고 사항
섹션 제목: “보안 참고 사항”SPI는 보안 경계이기도 합니다. HtmlSecurityPolicyInterface와 ExternalResourcePolicyInterface는 신뢰할 수 없는 HTML이 렌더러에 도달하기 전에 수행할 수 있는 작업을 제약하는 기본 거부(deny-by-default) 계약입니다. CryptoPolicyInterface는 서명 및 암호화에 대한 알고리즘과 키 강도 선택을 제어합니다. 이들은 계약이므로, 통합 담당자는 엔진을 포크하지 않고도 더 엄격한 정책을 제공할 수 있습니다. 보안 관련 정책은 stable 등급에 고정하세요. 실험적(experimental) 정책 계약은 마이너 릴리스 사이에서 형태가 변경될 수 있습니다. 서명 및 보안 정책 도메인 페이지에는 전체 위협 모델과 규범적 참조가 담겨 있습니다.
적합성
섹션 제목: “적합성”이 개요는 직접적인 규범적 주장을 하지 않으며, 각 도메인 페이지가 자체 citations 블록을 렌더링합니다. signing 계약은 ISO 32000-2 §12.8(디지털 서명)과 ETSI EN 319 142(PAdES 베이스라인)에 매핑됩니다. PDF/A 관리자는 ISO 19005-4에 매핑됩니다. 절 수준의 적합성 표는 signing, security-policy, extraction 페이지를 참조하세요.
상업적 맥락
섹션 제목: “상업적 맥락”Pro 및 Enterprise 에디션은 여러 핵심 계약 뒤의 프로덕션 코드를 구현합니다: LtvManagerInterface(장기 검증), PdfAManagerInterface(PDF/A 적용), 하드웨어 보안 모듈(HSM) 및 지연 서명자, 바코드 인코더, 임베딩 및 벡터 인덱스 계약. Core는 인터페이스를 공개하고 고정하며, Premium 패키지는 구현을 제공합니다. 이를 통해 오픈 소스 엔진을 Apache-2.0 라이선스로 유지하면서도, 상용 배포에는 API 변경 없는 드롭인 업그레이드를 제공합니다.
참고 항목
섹션 제목: “참고 항목”- Contracts / Document — PDF 문서, 팩토리, 레지스트리 계약.
- Contracts / Signing — 서명자, HSM, 타임스탬프, LTV 계약.
- Contracts / Security Policy — 암호화, HTML, 리소스 정책 계약.
- Contracts / Typography — 글꼴 레지스트리 및 텍스트 전처리 계약.
- Contracts / Extraction — 인스펙터, PDF/A, 임베딩, 전자 송장 계약.
- Core — 이러한 계약을 충족하는 구체 클래스.
- Event —
Contracts와 함께 공개되는 이벤트 SPI 상응물.