Chọn API tạo PDF trông có vẻ dễ cho đến khi bắt đầu. Có nhiều nhà cung cấp, trang marketing nghe giống nhau, và tradeoff thật chỉ lộ ra sau hàng nghìn tài liệu chạy trong production.
Checklist này dùng được cho đánh giá vendor. Nó trung lập và dựa trên các sự cố thật trong procurement, vận hành và post-mortem. Có tám câu hỏi; nếu chưa có câu trả lời rõ, bạn chưa đủ thông tin để chọn.
1. Input là HTML, JSON hay template DSL?
Đây là câu hỏi quan trọng nhất vì nó quyết định team sẽ viết gì và debug gì khi có sự cố.
- HTML/CSS (Puppeteer, DocRaptor, Prince): quen thuộc, rất linh hoạt, runtime đắt, khó determinism.
- JSON / dữ liệu có cấu trúc (gPdf): render rẻ, byte-identical, nhưng cần mapper từ data model sang document model.
- Template DSL (PDFKit, ReportLab, Apache PDFBox): toàn quyền kiểm soát, đồng thời tự chịu pagination, layout và font fallback.
Không có đáp án đúng cho mọi team. Có đáp án sai với team của bạn. Hãy hỏi engineer muốn debug bug pagination ba tiếng trong model nào.
2. Cold-start latency bao nhiêu và có dự đoán được không?
WASM hoặc native binary có thể start trong microseconds. Chromium-based có thể mất seconds. Khác biệt hiện rõ khi traffic spike.
Hỏi p99 request đầu tiên trên cold worker, bao lâu worker lạnh lại, và có publish cold-start data trên status page không.
3. Chi phí mỗi render được tính thế nào?
Các mô hình thường gặp:
- Theo trang: dễ dự đoán, nhưng đắt khi scale.
- Subscription + overage: rẻ ở nhiều volume, nhưng cần ước lượng usage.
- Compute-based: bạn trả tiền Lambda, container, memory Chromium và cold start.
Tính bill ở traffic hiện tại, 5x và 50x. Đường cong chi phí quan trọng hơn giá headline.
4. Output có deterministic không?
Cùng input phải ra cùng bytes. Điều này cần cho PDF diff trong CI, lưu trữ thuế, archive hash và legal review.
Renderer dựa trên browser thường không deterministic giữa các version Chromium. Native renderer thường tốt hơn. Hãy hỏi bytes có đổi khi engine update không.
5. Fonts, CJK và RTL được xử lý thế nào?
Font là nguồn sự cố production phổ biến. Ban đầu mọi thứ ổn, rồi khi mở rộng sang script khác, PDF hiện □□□□.
Hỏi script nào được bundle sẵn, glyph lạ fallback hay tofu, có custom font theo request không, và có RTL shaping không.
6. Hỗ trợ compliance profiles nào?
Nếu có thể cần invoice EU, PDF/A archive, XML attachment hoặc digital signature, hãy hỏi native support. “Convert bằng tool khác sau” nghĩa là bạn sở hữu thêm một pipeline.
Câu trả lời tốt thường là { profile: "PDF/A-3b" } hoặc { einvoice: { format: "factur-x", xml: "..." } }.
7. Rendering có stateless không? Documents đi đâu?
Stateless rendering nhận request, trả PDF và không lưu gì. Bạn tự quản persistence. Đây là lựa chọn tốt cho workload có compliance.
Stateful rendering lưu PDF phía vendor và trả signed URL. Tiện, nhưng third party giữ copy của mọi document.
8. Khi renderer fail thì sao?
Renderer nào cũng có lúc fail. Kiểm tra structured 4xx/5xx, idempotent retry, phí cho failed render, status page, webhooks, p50/p99 theo region và synthetic probes.
gPdf trả lời thế nào
| # | Câu hỏi | Câu trả lời của gPdf |
|---|---|---|
| 1 | Input | JSON DocumentRequest |
| 2 | Cold start | 5-20 ms, V8 isolate, không browser |
| 3 | Cost | $0/$5/$8/$12/tháng; $0.00005/page overage |
| 4 | Determinism | Byte-identical trên cùng engine version |
| 5 | Fonts | NotoSans CJK + Latin fallback embedded |
| 6 | Compliance | PDF/A-1b/2b/3b/4 + Factur-X / ZUGFeRD |
| 7 | Stateless | Có, không document storage |
| 8 | Failure | Public status page, structured errors, idempotent |
Nếu input thật sự là HTML không thể refactor, DocRaptor hoặc Prince có thể phù hợp hơn.
Tóm tắt
Đừng hỏi “API PDF nào tốt nhất”. Hãy hỏi tám câu này, chấm điểm câu trả lời và chọn vendor phù hợp với workload thật. Với invoice, receipt và structured documents, hãy thử gPdf trong Playground.