Blog

Chọn PDF API trong năm 2026: 8 câu hỏi nên hỏi trước

Một khung đánh giá trung lập khi chọn API tạo PDF. Tám câu hỏi thật sự dự đoán liệu 12 tháng sau đội của bạn có còn hài lòng hay không.

Chọn một API tạo PDF trông có vẻ đơn giản, cho đến khi bạn bắt đầu triển khai. Có khoảng 40 nhà cung cấp, trang marketing nghe na ná nhau, và nhiều đánh đổi thật chỉ lộ ra sau vài nghìn tài liệu chạy trong production.

Đây là checklist bạn có thể mang vào buổi đánh giá vendor: trung lập với nhà cung cấp, rút ra từ những sự cố thực tế mà các đội gặp trong mua sắm và post-mortem. Tám câu hỏi. Nếu không lấy được câu trả lời rõ ràng cho cả tám, bạn chưa có đủ thông tin để chọn.

1. Định dạng đầu vào là gì: HTML, JSON hay template DSL?

Đây là câu hỏi quan trọng nhất. Câu trả lời quyết định đội của bạn sẽ viết gì và sẽ debug gì lúc 2 giờ sáng.

  • HTML/CSS (Puppeteer, DocRaptor, Prince): quen thuộc, cực kỳ linh hoạt, tốn kém lúc chạy, khó bảo đảm tính xác định.
  • JSON / dữ liệu có cấu trúc (gPdf): rẻ khi render, có thể tạo đầu ra byte-identical, nhưng cần viết một mapper nhỏ từ data model của bạn sang document model.
  • Template DSL (PDFKit, ReportLab, Apache PDFBox): toàn quyền kiểm soát, đồng thời chịu toàn bộ trách nhiệm: phân trang, layout, fallback font đều do bạn tự xử lý.

Không có câu trả lời đúng tuyệt đối. Chỉ có câu trả lời sai đối với đội của bạn. Hãy hỏi engineer của bạn muốn debug lỗi phân trang kéo dài 3 giờ trong mô hình nào.

2. Cold-start latency là bao nhiêu và có dự đoán được không?

Một số renderer khởi động trong microsecond (WASM hoặc native binary). Một số mất vài giây (Chromium-based). Khác biệt này gần như vô hình cho đến khi traffic tăng đột biến.

Nên hỏi vendor:

  • “p99 latency của request đầu tiên tới một worker cold là bao nhiêu?”
  • “Sau request cuối cùng của tôi bao lâu thì worker cold trở lại?”
  • “Các bạn có công bố status page có dữ liệu cold start không?”

Nếu họ không trả lời câu đầu bằng một con số, hãy giả định đó là điểm yếu.

3. Chi phí mỗi lần render được tính thế nào?

Ba kiểu phổ biến, xếp theo mức độ thường gây bất ngờ:

  • Tính theo PDF hoặc theo trang (Anvil 0,10 USD/PDF, DocRaptor 89 USD/100K): dễ dự toán, dễ đưa vào ngân sách, nhưng đắt ở quy mô lớn.
  • Gói thuê bao kèm overage (gPdf 5-12 USD/tháng + 0,00005 USD/trang vượt): rẻ ở hầu hết volume, nhưng khó dự báo nếu bạn chưa chạy thử usage thật.
  • Tính theo compute (self-host Puppeteer trên Lambda): bạn trả trực tiếp hóa đơn compute, gồm cả cold start và bộ nhớ Chromium.

Trước khi ký, hãy tính hóa đơn THỰC TẾ ở ba mức traffic: hiện tại, 5 lần và 50 lần. Hình dạng của đường cong chi phí quan trọng hơn con số headline.

4. Đầu ra có deterministic không?

Determinism, tức cùng input tạo cùng bytes, nghe có vẻ học thuật cho đến khi bạn thật sự cần nó.

Bạn cần điều này khi:

  • Diff PDF trong CI để bắt thay đổi template ngoài ý muốn.
  • Lưu tài liệu theo yêu cầu e-invoice hoặc luật thuế, nơi PDF đã lưu và PDF render lại phải khớp.
  • Hash PDF để chứng minh tính toàn vẹn lưu trữ.
  • Đưa output đã render vào quy trình review pháp lý.

Renderer dựa trên browser (Puppeteer, bất kỳ thứ gì dựa trên Chromium) KHÔNG deterministic giữa các patch version. Native binary renderer (Prince, gPdf) thường ổn định hơn. Hãy hỏi thẳng: “Output bytes của tôi có đổi nếu các bạn phát hành bản cập nhật renderer không?”

5. Renderer xử lý font thế nào, đặc biệt CJK và RTL?

Đây là câu hỏi đã gây tốn kém cho nhiều đội hơn bất kỳ chủ đề PDF nào khác.

Failure mode rất quen thuộc: bạn ra mắt ở thị trường đầu tiên, font vẫn ổn. Sáu tháng sau, bạn mở rộng sang một thị trường dùng hệ chữ mà renderer không có glyph. PDF bắt đầu xuất hiện các ô ▢▢▢▢. Khách hàng escalation. Đội của bạn mất hai sprint thêm font vào Dockerfile.

Nên hỏi:

  • “Những hệ chữ nào được bundle sẵn mà không cần cấu hình thêm? Latin, CJK, Cyrillic, Devanagari, Arabic, Hebrew?”
  • “Khi gặp glyph không biết, hệ thống fallback hay hiện tofu?”
  • “Tôi có thể thêm custom font tại request time không, hay phải deploy trước?”
  • “Có hỗ trợ shaping cho văn bản RTL không?”

Câu trả lời tốt: “Chúng tôi embed NotoSans CJK và một bộ Noto fallback; glyph chưa biết sẽ fallback sang Noto Symbols.” Câu trả lời kém: “Có, chúng tôi hỗ trợ font.”

6. Có hỗ trợ profile tuân thủ nào?

Nếu doanh nghiệp của bạn có thể một ngày nào đó cần:

  • Phát hành hóa đơn tại EU (Factur-X / ZUGFeRD / EN 16931, bắt buộc ở DE/FR/IT/PL từ 2026)
  • Lưu trữ tài liệu theo SOX, HIPAA hoặc quy định retention của GDPR (PDF/A)
  • Nộp hồ sơ y tế (PDF/A-3 có XML đính kèm)
  • Nhúng chữ ký số (PAdES)

…thì hãy hỏi renderer hỗ trợ native những profile tuân thủ nào. Câu trả lời tệ là: “bạn có thể chạy một công cụ khác để chuyển đổi sau”. Khi đó bạn đang sở hữu thêm một pipeline nhiều bước.

Câu trả lời tốt thường là một flag đơn giản. Ví dụ, gPdf nhận settings.profile: "pdfa-3b" cùng một block settings.e_invoicestandard: "factur_x" và CII XML nhúng. Built-in luôn nhẹ vận hành hơn rất nhiều so với gắn thêm ở cuối pipeline.

7. Rendering có stateless không? Tài liệu của tôi đi đâu sau khi render?

Đây là hai câu hỏi liên quan.

Stateless rendering nghĩa là request đi vào, PDF được tạo ra, và không có gì được lưu lại. Bạn tự xử lý persistence: S3, database của bạn, hoặc bất kỳ nơi nào bạn kiểm soát. Đây là mô hình phù hợp cho workload nặng về compliance, vì renderer không bao giờ trở thành bên lưu giữ dữ liệu của bạn.

Stateful rendering nghĩa là vendor lưu PDF, thường trên CDN của họ, rồi trả cho bạn một signed URL. Điều này tiện cho workflow nhẹ như “gửi khách hàng một link”, nhưng rủi ro hơn với workflow bị quản lý, vì giờ có bên thứ ba giữ bản sao của mọi tài liệu bạn từng render.

Nên hỏi:

  • “Rendering mặc định có stateless không?”
  • “Nếu các bạn lưu tài liệu, nó được lưu ở khu vực địa lý nào?”
  • “Giữ trong bao lâu?”
  • “Tôi có thể nhận cam kết bằng văn bản về stateless rendering cho review compliance không?”

Nếu câu trả lời mơ hồ, đội privacy/legal của bạn rất có thể sẽ biến nó thành vấn đề sau 9 tháng.

8. Khi renderer lỗi thì chuyện gì xảy ra, và tôi biết bằng cách nào?

Renderer nào cũng có lúc lỗi. Câu hỏi là:

  • Lỗi xuất hiện ra sao? HTTP 500 với stack trace? 4xx có structured error? Hay một PDF rỗng?
  • Retry policy là gì? Có idempotent không? Render lỗi có bị tính phí không?
  • Vendor cung cấp instrumentation gì? Status page? Webhook sự cố? Dashboard p50/p99 theo khu vực?
  • Có synthetic probe không? Vendor có tự monitor endpoint public của họ, hay chờ bạn gửi ticket?

Một phép thử nhanh: mở status page của vendor ngay bây giờ. Nếu không có, không realtime, hoặc chỉ hiện “all systems operational” mà không có chi tiết, đó chính là mức minh bạch về reliability bạn sẽ nhận sau khi mua.

Tham khảo: gPdf công bố /status với dữ liệu synthetic probe và Cloudflare Analytics trong 7 ngày gần nhất.

gPdf trả lời tám câu hỏi này thế nào

Vì đây là blog của chúng tôi và bạn có thể nghi ngờ bộ câu hỏi được chọn có lợi cho gPdf, đây là scorecard thẳng thắn:

# Câu hỏi Câu trả lời của gPdf
1 Định dạng đầu vào JSON DocumentRequest (dữ liệu có cấu trúc)
2 Cold start 5-20 ms (V8 isolate, không browser)
3 Mô hình chi phí 0/5/8/12 USD mỗi tháng; 0,00005 USD/trang vượt
4 Determinism Byte-identical, được bảo đảm trong cùng engine version
5 Font NotoSans CJK + Latin fallback được embed
6 Compliance PDF/A-1b/2b/3b/4 + Factur-X / ZUGFeRD attachment built-in
7 Stateless Có, theo contract: không lưu tài liệu ở bất kỳ đâu
8 Lỗi và khả năng quan sát Status page public có xu hướng 7 ngày; structured 4xx/5xx; idempotent

Nơi chúng tôi thua: Q1, nếu input của bạn thật sự là HTML không thể refactor, ví dụ báo cáo do người dùng tạo hoặc template legacy. Với bài toán đó, DocRaptor hoặc Prince là câu trả lời đúng hơn.

TL;DR

Đừng hỏi “PDF API nào tốt nhất”. Hãy hỏi tám câu trên, chấm điểm câu trả lời, rồi chọn vendor khớp với workload thật của bạn. Đội từng thua một deal procurement trước đối thủ rẻ hơn một chút vì bị câu hỏi số 5 làm bất ngờ sau 9 tháng sẽ nói với bạn điều tương tự.

Nếu workload của bạn khớp với cách gPdf được xây dựng, Playground mất khoảng 30 giây để thử. Nếu không khớp, chúng tôi vẫn sẵn sàng chỉ bạn tới công cụ phù hợp hơn: thường là DocRaptor cho bài toán HTML-shaped, Prince cho self-hosted, hoặc Puppeteer nếu input của bạn thật sự là web page tùy ý.