NextPDF 디자인 철학
Spec: ISO/IEC 25010 ISO/IEC 25010 Spec: ISO 32000-2 ISO 32000-2 Evidence: Design principle
한눈에 보기
섹션 제목: “한눈에 보기”이 페이지는 모든 NextPDF API 결정이 따라야 하는 원칙을 명시합니다. 원칙은 의도적으로 적게 두었습니다. 외워서 말할 수 없는 원칙은 압박 속에서 적용할 수 없기 때문입니다.
가장 먼저 읽어야 할 페이지입니다. 다른 Insider_ 페이지들은 이 원칙들이 구체적인 지점에서 어떻게 작동하는지 보여 줍니다. 이 페이지는 그 원칙들에 이름을 붙여 나머지 페이지들이 의미를 갖게 합니다.
왜 중요한가
섹션 제목: “왜 중요한가”PDF는 명확한 입장을 가질 만큼 오래되었고, 추측을 그냥 넘기지 않을 만큼 엄격합니다. 서명은 자신이 포함하는 바이트만 정확히 포함합니다. 폰트는 임베드되었거나 임베드되지 않았거나, 둘 중 하나입니다. 보존용 프로파일은 유효하거나, 그렇지 않으면 몇 달 뒤 달가워하지 않을 누군가 앞에서 감사를 통과하지 못합니다.
입력이 모호할 때 라이브러리에는 선택지가 있습니다. 추측하고 조용히 넘어갈 수도 있고, 멈추고 그 사실을 알릴 수도 있습니다. 첫 번째 방식은 데모에서는 더 친절해 보입니다. 그 대가로 무엇이 잘못되었는지 흔적도 없는 운영 장애를 떠안게 됩니다. NextPDF는 두 번째 방식을 선택합니다. 변호할 수 있는 결과를 얻기 위해 덜 편안한 첫인상을 받아들입니다. 소프트웨어 품질 표준은 이 절충을 직접적으로 명명합니다. 페일세이프(fail-safe) 동작은 제품이 실패할 때 정의되지 않은 상태로 계속 진행하지 않고 안전한 상태로 되돌아가는 능력입니다( Spec: ISO/IEC 25010, §3 ISO/IEC 25010 §3 ).
NextPDF는 우선순위에 따라 다섯 가지 원칙 위에 세워져 있습니다.
- 명시적인 것이 암묵적인 것을 이깁니다. 의도가 중요하다면, 그것을 명시합니다. 엔진은 서명 수준, 출력 모드, 적합성 대상을 문맥에서 추론하지 않습니다.
- 빠르게 실패하고, 명확하게 실패하고, 일찍 실패합니다. 유효하지 않은 입력은 단 한 바이트가 기록되기 전에, 원인을 명시하는 메시지와 함께 거부됩니다.
- 오류는 API 표면입니다. 실패는 구체적이고, 타입이 지정되어 있으며, 구조화된 컨텍스트를 담습니다. 우연히 생긴 것이 아니라 설계된 것입니다.
- 경계는 발견되는 것이 아니라 명시되는 것입니다. 모든 주장은 어디에서 멈추는지 밝힙니다. “필요하지만 충분하지는 않다”는 NextPDF가 의도적으로 명시하는 표현입니다.
- 아무것도 조용히 저하된 상태로 넘어가지 않습니다. 엔진은 완성된 것처럼 보이지만 절반만 올바른 산출물을 반환하지 않습니다.
그 밖의 모든 것 — 플루언트 빌더, 일회용 문서, 엄격한 타이핑 —은 이 원칙들에서 파생됩니다.
NextPDF가 접근하는 방식
섹션 제목: “NextPDF가 접근하는 방식”이 원칙들은 포스터가 아닙니다. 소스 코드에서 구체적인 형태로 드러나며, 서로를 강화합니다.
아래 표는 각 원칙을 엔진의 어느 부분에서 볼 수 있는지, 그리고 그 원칙이 없을 때 어떤 대가를 치르는지와 대응시킵니다.
| 원칙 | NextPDF에서 나타나는 방식 | 반대로 할 때의 대가 |
|---|---|---|
| 명시적인 것이 암묵적인 것을 이긴다 | setSignature(certInfo:, level:)는 PAdES 수준을 필수 명명 인자로 받습니다 — “auto” 수준은 없습니다 | 의무가 요구하지 않은 프로파일로 서명된 문서를 검증 시점에서야 발견하게 됨 |
| 빠르게 실패하고, 명확하게 실패한다 | save()는 렌더링 전에 스트림 래퍼 경로나 널바이트 경로를 거부합니다. setSignature() 뒤에 save()를 호출하면 서명되지 않은 파일을 내보내는 대신 예외를 던집니다 | 경로 탐색을 통한 쓰기, 또는 아카이브에 “서명되지 않았지만 서명되었다고 믿는” PDF |
| 오류는 API 표면이다 | 하나의 추상 기반 예외와 구체적으로 타입이 지정된 하위 클래스들이 있으며, 각각 로그와 APM을 위해 구조화된 getContext()를 노출합니다 | 막연한 스택 트레이스와 추측으로 허비하는 긴 오후 |
| 경계는 명시된다 | 프로세스 내 적합성 검사는 발견 사항을 반환하며, 최종 판정은 독립적인 검증기의 몫이라고 명시합니다 | 감사관이 반증하는 “예외가 없으니 적합한 것이 틀림없다”는 결론 |
| 아무것도 조용히 저하된 상태로 넘어가지 않는다 | 보존용 타임스탬프 경로는 필수 딕셔너리가 빠진 프로파일을 내보내는 대신, 절반만 작성된 프로파일을 반환하기를 거부합니다 | 장기 검증 프로파일처럼 보이지만 조용히 그렇지 않은 결과물 |
이 원칙들을 함께 읽으면 하나의 입장이 드러납니다. 엔진은 자신만만한 “아마도”보다 정직한 “아니오”를 제공하려 합니다. 이는 비관주의가 아닙니다. PDF가 흔히 법적 산출물이라는 인식입니다. 잘못된 법적 산출물은 아예 만들어지지 않은 것보다 더 나쁩니다.
증거가 말하는 것
섹션 제목: “증거가 말하는 것”이 페이지는 Evidence: Design principle 성격의 진술입니다. 이 원칙들은 의도적인 결정으로, 측정된 것이 아니라 논증된 것입니다. 어떤 원칙이 외부 분야에서 이미 이름 붙여진 경우, 이 페이지는 그 추론이 단지 사내 의견에 그치지 않도록 그것에 근거를 둡니다.
- “정의되지 않은 상태로 계속하기보다 거부한다”는 입장은 Spec: ISO/IEC 25010 ISO/IEC 25010 §3의 페일세이프(fail-safe) 품질 속성입니다 — 실패 시 스스로를 안전한 상태에 두는 제품입니다. 같은 계열의 결함 허용(fault tolerance) 은 시스템이 결함에도 불구하고 의도한 대로 계속 동작하는 정도입니다. NextPDF는 그 노력을 결함을 감추는 데가 아니라, 결함을 감지하고 멈추는 데 돌립니다.
- “채택 전에 경계를 명시한다”는 입장은 적절성 인식 가능성(appropriateness recognizability) ( Spec: ISO/IEC 25010, §3.26 ISO/IEC 25010 §3.26 )입니다. 문서와 첫인상으로 적합성을 판단할 수 있는 능력입니다.
- 이 모든 것이 중요한 PDF 특화 이유는 Spec: ISO 32000-2, §12.8 ISO 32000-2 §12.8 입니다. 서명의 바이트 범위는 그것이 포함하는 바이트만 정확히 보호하며 그 이상은 보호하지 않으므로, 서명된 문서를 “친절하게” 다시 쓰거나 그 주변을 추측하는 엔진은 전혀 도움이 되지 않습니다.
개별 원칙들은 각자의 페이지에서 실제 엔진 소스를 대상으로 입증됩니다 — 추측을 거부하는 API 및 기능으로서의 오류 페이지가 Evidence: Code-backed 증거를 담고 있습니다. 이 페이지는 ‘왜’이고, 그 페이지들은 ‘무엇’을 다룹니다.
실전 예제
섹션 제목: “실전 예제”이 원칙들은 평범한 사용 코드 몇 줄 안에서도 드러납니다. 서명 호출은 의도를 명시적으로 밝힙니다. 엔진은 오해를 부르는 무언가를 내보내기보다 일찍 거부합니다.
<?php
declare(strict_types=1);
use NextPDF\Core\Document;use NextPDF\Exception\NotImplementedException;use NextPDF\Security\Signature\CertificateInfo;use NextPDF\Security\Signature\SignatureLevel;
$document = Document::createStandalone();$document->setTitle('Service Agreement 2026-0042');$document->addPage();$document->setFont('helvetica', '', 12);$document->cell(0, 10, 'This agreement is configured for a PAdES signature.', newLine: true);
// Explicit beats implicit: the PAdES level is a required, named argument.// There is no inferred or "auto" level.$document->setSignature( certInfo: new CertificateInfo( certificate: $certificatePem, privateKey: $privateKeyPem, ), level: SignatureLevel::PAdES_B_B,);
try { // Fail fast, no silent degradation: rather than emit an UNSIGNED file // that the caller believes setSignature() signed, the high-level path // refuses and names the supported route. $document->save('/srv/output/agreement.pdf');} catch (NotImplementedException $e) { // The message identifies the feature and the follow-up, not a stack // trace: "... is not implemented in this release. <actionable follow-up>" error_log($e->getMessage());}핵심은 서명이 어떻게 작동하는지가 아닙니다. 핵심은 하나의 스니펫에서 세 가지 원칙을 볼 수 있다는 점입니다. 의도가 명시되고(level:), 실패는 이르고 이름이 붙으며, 엔진은 자신의 상태에 대해 거짓말하는 문서를 만들기를 거부합니다.
흔한 오해
섹션 제목: “흔한 오해”가장 흔한 오해는 이 원칙들이 NextPDF를 “사용하기 더 어렵게” 만든다는 생각입니다. 이 원칙들은 잘못 사용하기 더 어렵게 만듭니다. 필수 인자는 예상 밖의 암묵적 기본값을 하나 줄여 줍니다. 이른 예외는 아카이브에 손상된 산출물을 하나 줄여 줍니다. 이 마찰은 실수의 비용이 큰 곳 — 운영 환경, 감사, 법정 —이 아니라, 실수의 비용이 작은 곳 — 호출 지점, 개발 단계 —에 의도적으로 배치됩니다.
두 번째 오해는 “의견이 강한”이 “융통성이 없는”을 뜻한다는 생각입니다. 그렇지 않습니다. 엔진은 여러분의 문서가 아니라 정확성과 의도에 대해 의견을 가집니다. 레이아웃, 콘텐츠, 폰트, 구조는 여전히 여러분이 완전히 제어합니다. 그 의견은 추측이 안전하지 않은 곳에서 여러분을 대신해 추측하지 않겠다는 입장입니다.
한계와 경계
섹션 제목: “한계와 경계”이 페이지는 설계 의도를 명시합니다. 이 페이지 자체가 동작 명세는 아닙니다. 이 원칙들은 결정이 내려지는 방식을 설명할 뿐, 특정 메서드를 보장하지는 않습니다. 각 메서드의 정확한 계약은 레퍼런스와 증거 수준이 명시된 해당 Insider_ 페이지에서 확인해야 합니다.
이 원칙들은 또한 절대적인 물리 법칙도 아닙니다. 판단과 함께 적용되는 우선순위입니다. 두 원칙이 충돌하는 경우(더 엄격한 거부 대 더 관대한 기본값), 위의 우선순위 순서가 우열을 가리는 기준이 됩니다. 특정 모듈은 그럼에도 근거 있는 예외를 문서화할 수 있습니다. 그럴 때 그 예외는 가정되는 것이 아니라 명시적으로 기록됩니다.
끝으로, 여기서 “설계 원칙”을 증거 수준으로 두는 것은 의도적입니다. 이 페이지는 논증합니다. 벤치마크하지는 않습니다. 수치, 테스트 또는 조항으로 뒷받침해야 하는 주장은 여기가 아니라 그 증거를 보유한 페이지에서 제시됩니다.
관련 문서
섹션 제목: “관련 문서”- 추측을 거부하는 API — 명시적 의도 원칙과 빠른 실패 원칙을 실제 API를 대상으로 보여 줍니다.
- 기능으로서의 오류 — 설계된 표면으로서의 타입 지정 예외 계층입니다.
- PHP 8.4 기반 — 이 원칙들이 바람으로만 그치지 않고 강제될 수 있게 해 주는 언어 기능입니다.
용어집
섹션 제목: “용어집”- 설계 원칙(증거 수준) — 그 주장이 의도적인 설계 결정이며, 벤치마크나 단일 테스트로 측정된 것이 아니라 의도와 이를 뒷받침하는 표준을 근거로 논증된 페이지입니다.
- 페일세이프(fail-safe) — 소프트웨어 품질 속성입니다. 실패 시 제품이 정의되지 않은 상태로 계속 진행하지 않고 안전한 상태로 되돌아갑니다. NextPDF가 추측하기보다 거부하는 이유입니다.
- 빠른 실패(fail fast) — 계속 진행하다가 나중에 모호하게 실패하는 대신, 유효하지 않은 입력을 가능한 가장 이른 지점에서 명확한 원인과 함께 거부하는 것입니다.
- PAdES — PDF Advanced Electronic Signatures, PDF 문서 서명을 위한 ETSI 프로파일 계열입니다(B-B, B-T, B-LT, B-LTA). 여기서는 처음 사용될 때 풀어서 설명하며, 서명 페이지에서 깊이 있게 다룹니다.
- 필요하지만 충분하지는 않다 — 프로세스 내 검사가 실질적인 신호이기는 하지만 적합성 판정은 아닐 때 사용하는 의도적인 표현입니다. 권위 있는 판정은 독립적인 검증기에 속합니다.