TMF API trong Telco nhìn trên tài liệu có thể rất chuẩn, nhưng khi đi vào vận hành, ranh giới tích hợp giữa các hệ thống mới là nơi phát sinh nhiều vấn đề nhất. Tôi từng gặp một trường hợp khá điển hình. Hai hệ thống cùng dùng trường dữ liệu effectiveDate trong API đặt hàng, nhưng lại hiểu theo hai nghĩa khác nhau. Hệ thống quản lý khách hàng hiểu đó là ngày khách ký hợp đồng. Hệ thống tính cước hiểu đó là ngày bắt đầu tính tiền. Khách ký ngày 25, dịch vụ đến ngày 28 mới kích hoạt nhưng hệ thống tính cước đã bắt đầu tính tiền từ ngày 25.
Một khách thì nhỏ nhưng nhân lên hàng nghìn đơn mỗi tháng, sai lệch chỉ lộ ra lúc đối soát cuối kỳ. Lúc đó, đây không còn là chuyện một trường dữ liệu bị hiểu nhầm. Nó là lỗi thiết kế ở ranh giới tích hợp.
> Ranh giới tích hợp hiểu đơn giản là nơi hai hệ thống thống nhất với nhau về dữ liệu, trạng thái và trách nhiệm xử lý. Nếu ranh giới đó mơ hồ, mỗi hệ thống vẫn có thể đúng theo cách của mình, nhưng toàn bộ luồng nghiệp vụ lại sai.
Điều đáng nói là cả hai hệ thống đều tuyên bố tuân thủ TMF API. Vậy cùng chuẩn mà vẫn sai, thì chuẩn đang giải quyết được phần nào?
TMF API giải quyết được phần hợp đồng trao đổi, phần triển khai vẫn là bài toán riêng
> TMF API là bộ API chuẩn của TM Forum, dùng để chuẩn hóa cách các hệ thống Telco trao đổi dữ liệu và nghiệp vụ với nhau, như đặt hàng, quản lý khách hàng, sản phẩm, dịch vụ hoặc tài nguyên.
Theo trải nghiệm của tôi, giá trị lớn nhất của TMF API là giúp đội tích hợp bỏ qua phần tốn thời gian nhất là đọc hiểu mô hình dữ liệu từ đầu. Nếu không có chuẩn chung, chỉ riêng việc hiểu API đã mất vài ngày. Sau đó là mapping dữ liệu, xử lý các tình huống lệch nghiệp vụ và kiểm thử. Một tích hợp tưởng nhỏ như thêm cổng thanh toán hoặc hoá đơn điện tử có thể kéo dài một đến hai tuần. Nếu dùng TMF API đúng cách, phần đọc hiểu ban đầu được rút ngắn đáng kể. Đội kỹ thuật có thể tập trung vào phần khác biệt thật sự giữa hệ thống đang chạy và hệ thống cần tích hợp. Thời gian có thể rút xuống còn vài ngày.
Tuy nhiên, TMF API chỉ chuẩn hoá hợp đồng trao đổi ở bên ngoài. Cách mỗi nhà cung cấp triển khai bên trong vẫn hoàn toàn do họ quyết định. Hai nhà cung cấp cùng nói mình tuân thủ TMF vẫn có thể xử lý tình huống đặc biệt khác nhau, trả lỗi khác nhau, chia dữ liệu theo trang khác nhau hoặc mở rộng dữ liệu theo cách khác nhau. Vì vậy, lớp chuyển đổi dữ liệu, kiểm thử và xác minh hành vi thực tế của hệ thống vẫn luôn tồn tại. Không có chuyện cắm vào là chạy.
Đó là trên lý thuyết. Còn thực tế triển khai thì sao?
Case thực tế: Trên tài liệu thì chuẩn, mở code ra thì mỗi nơi một kiểu
Trên tài liệu thì mọi thứ rất đẹp. Đường dẫn API đặt đúng chuẩn TMF, tài liệu ghi rõ là tuân thủ chuẩn và sơ đồ kiến trúc nhìn rất gọn gàng. Nhưng khi đi sâu vào dữ liệu và nghiệp vụ thực tế, đội kỹ thuật mới phát hiện mỗi bên đã chỉnh theo một kiểu riêng để phù hợp hệ thống của mình. Kết quả là nhìn bên ngoài thì giống TMF, nhưng bên trong vẫn hoàn toàn tuỳ biến riêng. Nhà cung cấp khác nhìn vào tưởng đã theo chuẩn, đến lúc tích hợp thật mới biết phải mapping lại dữ liệu gần như từ đầu.
Thực ra TMF đã có sẵn cơ chế mở rộng để xử lý chuyện này. Cách làm đúng là giữ phần lõi theo chuẩn chung, còn nghiệp vụ riêng thì đưa vào phần mở rộng. Như vậy hệ thống vẫn giữ được hợp đồng trao đổi chung nhưng vẫn đủ linh hoạt cho đặc thù từng doanh nghiệp. Ngược lại, nếu viết lại toàn bộ dữ liệu trao đổi rồi chỉ giữ đường dẫn API giống TMF, thì gần như mất hết ý nghĩa chuẩn hoá. Khi đó TMF chỉ còn là cái vỏ.
Ở Việt Nam, với một số khách hàng tôi từng làm việc, TMF API thường rõ nhất ở giai đoạn đầu. Về sau, hệ thống phát triển theo hướng nào ra nhanh nhất. Chuẩn API bắt đầu lệch theo từng đội, từng phân hệ, từng áp lực triển khai. Đến một lúc, TMF không còn là chuẩn vận hành nữa. Nó chỉ còn là một lớp tên gọi ban đầu.
Chuẩn API giải quyết được phần hợp đồng trao đổi. Thực tế triển khai cho thấy phần đó chưa đủ. Vậy cái gì quyết định hai hệ thống tích hợp đúng hay sai? Câu trả lời nằm ở cách thiết kế ranh giới tích hợp.
4 nguyên tắc thiết kế ranh giới tích hợp theo luồng nghiệp vụ
Ở các bài trước, tôi đã nói về ranh giới giao dịch, lớp điều phối và lớp ghi nhận hành trình. Nói ngắn gọn, đó là cách hệ thống giữ trạng thái tối thiểu của một giao dịch khi nó đi qua nhiều hệ.
> Tham khảo bài viết về Đứt gãy ranh giới giao dịch trong Telco
Khi đã có lớp đó, câu hỏi tiếp theo là: ranh giới tích hợp giữa các hệ thống phải được thiết kế như thế nào để luồng nghiệp vụ vận hành bền vững? Sau nhiều dự án, tôi rút ra bốn nguyên tắc.
-
Nguyên tắc 1: Mỗi hệ chỉ expose API, không truy cập DB của nhau. Nghe thì đơn giản, nhưng với hệ thống cũ, thay đổi được điều này là cả một bài toán tái cấu trúc. Nó không chỉ là đổi tư duy, mà là chấp nhận trả chi phí kỹ thuật thật.
-
Nguyên tắc 2: Đặt ranh giới theo luồng nghiệp vụ, không theo từng hệ thống. Trong viễn thông, chúng ta không vận hành riêng một hệ thống quản lý khách hàng, một hệ thống tính cước hay một hệ thống quản lý tài nguyên. Chúng ta vận hành một luồng nghiệp vụ từ đầu đến cuối: khách đăng ký dịch vụ, hệ thống kiểm tra điều kiện, giữ tài nguyên, kích hoạt dịch vụ, tính cước và đối soát. Nếu mỗi hệ tự định nghĩa trạng thái riêng mà không có quy ước chung, từng hệ có thể đều đúng. Nhưng khi ghép lại, toàn bộ hành trình vẫn sai.
-
Nguyên tắc 3: Dùng hợp đồng luồng nghiệp vụ. Tôi hay dùng khái niệm hợp đồng luồng nghiệp vụ để nói về tập quy ước chung này. Nó không phải một file tài liệu duy nhất cho cả hành trình. Thực tế vẫn là API của từng hệ thống. Nhưng các API đó phải cùng tuân theo một số quy ước chung: cùng mã giao dịch xuyên suốt, cùng cách gọi tên trạng thái, cùng cấu trúc dữ liệu cho các mốc chuyển trạng thái và cùng cách xử lý lỗi. Thiếu lớp quy ước này, mỗi hệ sẽ tự quyết định theo logic riêng. Đó là lúc đúng từng hệ nhưng sai khi ghép lại.
-
Nguyên tắc 4: Thêm correlationId/externalId xuyên suốt hành trình. Trong TMF API, các field như externalId hoặc correlationId thường xuất hiện trong nhiều đặc tả chuẩn khác nhau. Đây là những trường dữ liệu dùng để truy vết một giao dịch xuyên suốt qua nhiều hệ thống, giúp đội vận hành theo dõi được toàn bộ hành trình xử lý từ đầu đến cuối. Nhiều team bỏ qua vì chúng không bắt buộc. Nhưng đến khi sự cố xảy ra và đội vận hành phải truy vết một giao dịch qua năm hệ thống, những field không bắt buộc đó mới cho thấy giá trị thật.
4 nguyên tắc này giúp thiết kế ranh giới tích hợp rõ hơn. Nhưng khi vào vận hành, ranh giới đó cần được kiểm soát ở ba lớp.
Ranh giới tích hợp có 3 lớp: spec, adapter và vận hành
Cách nhìn đơn giản nhất là ranh giới tích hợp có ba lớp cần kiểm soát.
-
Lớp đầu tiên là spec: hai bên đồng ý gì trên giấy.
-
Lớp thứ hai là adapter: cách dịch giữa spec và thực tế triển khai bên trong từng hệ.
-
Lớp thứ ba là vận hành: ai nhiệm khi spec và thực tế không khớp.
Phần lớn dự án chỉ quan tâm lớp đầu tiên. Nhưng sự cố thường xảy ra ở lớp thứ hai và thứ ba. Vì vậy, tôi không đánh giá một dự án tích hợp chỉ bằng việc nó có dùng TMF API hay không. Tôi sẽ hỏi thêm: adapter nằm ở đâu, ai maintain, version cũ được support đến bao giờ, correlationId có xuyên suốt không, và khi hệ A lỗi ở bước 3 thì hệ B làm gì. Nếu những câu hỏi đó chưa có câu trả lời, chuẩn hóa vẫn mới nằm trên tài liệu.
Trong ba lớp này, adapter thường là nơi dễ hỏng nhất.
Adapter dễ hỏng nhất vì nó hay bị biến thành nơi chứa nghiệp vụ
> Adapter là lớp chuyển đổi tích hợp giữa mô hình chuẩn và cách triển khai thực tế của từng hệ thống. Khi tích hợp với nhà cung cấp, gần như luôn cần một lớp adapter.
Lớp này đứng giữa mô hình chuẩn và cách triển khai thực tế của từng hệ thống, giúp một hệ thống nói chuyện được với hệ thống khác mà không cần thay đổi quá sâu bên trong. Vai trò đúng của nó khá rõ: chuyển đổi dữ liệu, xử lý khác biệt trong cách gọi API và che bớt độ phức tạp kỹ thuật giữa các hệ thống.
Nhưng tôi từng thấy nhiều adapter dần biến thành nơi chứa nghiệp vụ. Ban đầu chỉ mapping vài trường dữ liệu. Sau đó thêm kiểm tra dữ liệu hợp lệ, chuyển đổi dữ liệu, rồi cả tính chiết khấu. Hai năm sau, adapter trở thành một hệ thống riêng mà không ai dám đụng vào. Đến lúc thay nhà cung cấp mới nhận ra: thứ phải thay không chỉ là hệ thống chính, mà còn cả lớp chuyển đổi tích hợp đi kèm.
Nguyên tắc của tôi rất rõ: lớp chuyển đổi tích hợp chỉ nên làm nhiệm vụ chuyển đổi và kết nối, không nên quyết định nghiệp vụ. Nếu trong lớp này bắt đầu xuất hiện quá nhiều logic kiểu khách thuộc nhóm này thì xử lý kiểu này, gói kia thì đổi cách tính khác, nghĩa là nghiệp vụ đang nằm sai chỗ. Lúc đó, nó không còn là lớp chuyển đổi tích hợp nữa. Nó đã trở thành một hệ thống nghiệp vụ ngầm.
Adapter phức tạp nhất khi phải dịch giữa nhiều version API cùng lúc. Rủi ro thật sự của version API thường nằm ở một chỗ ít ai ngờ.
Rủi ro thật của version API nằm ở giá trị mặc định, không phải ở endpoint
Về lý tưởng, hệ thống chỉ nên hỗ trợ phiên bản hiện tại và phiên bản ngay trước đó. Nhưng thực tế nhiều nơi vẫn phải giữ ba, bốn phiên bản cũ vì hệ thống chạy liên tục 24/7 và không đủ nguồn lực để ép toàn bộ đối tác nâng cấp cùng lúc. Kết quả là nhiều phiên bản phải chạy song song, thêm lớp chuyển đổi để giữ tương thích và thêm lớp trung gian cho các đối tác cũ. Lớp trung gian trong ngữ cảnh này là lớp đứng trước hệ thống mới để nhận yêu cầu theo định dạng cũ, chuyển sang định dạng mới ở bên trong, rồi trả kết quả về theo định dạng cũ. Nó giúp các hệ thống và đối tác cũ vẫn tiếp tục hoạt động trong khi phần lõi bên trong đã thay đổi.
Rủi ro lớn nhất thường nằm ở giá trị mặc định.
Tôi từng gặp một trường hợp phiên bản mới có thêm một trường dữ liệu ảnh hưởng tới hệ thống tính cước. Phiên bản cũ không có trường đó nên lớp chuyển đổi tự gán mặc định bằng 0. Một nhóm khách hàng đi qua phiên bản cũ bị tính sai trong hai tuần và chỉ được phát hiện khi đối soát.
Sai ở lớp chuyển đổi. Hậu quả nằm ở tiền.
Ở Việt Nam, chính sách dừng hỗ trợ phiên bản cũ gần như không tồn tại đúng nghĩa ở nhiều hệ thống lớn. Không ai dễ dàng tuyên bố một version cũ sẽ ngừng được hỗ trợ vào một ngày cụ thể, vì hệ thống Telco chạy liên tục 24/7, mỗi thị trường có lộ trình riêng, mỗi đối tác có năng lực nâng cấp khác nhau. Mô hình N-1, tức chỉ hỗ trợ phiên bản hiện tại và phiên bản ngay trước đó, là cách làm lý tưởng. Thực tế nhiều nơi vẫn đang duy trì tới N-3 hoặc N-4.
Khi nâng cấp API mà các đối tác ngoài như hóa đơn điện tử, ngân hàng hoặc cổng thanh toán chưa thể nâng cấp cùng lúc, hệ thống thường phải duy trì một lớp facade cho phiên bản cũ. Có thể hiểu facade là lớp đứng trước hệ thống mới, nhận yêu cầu theo định dạng cũ, chuyển đổi sang định dạng mới ở bên trong, rồi trả kết quả về theo định dạng cũ. Nhờ lớp này, các hệ thống cũ vẫn tiếp tục hoạt động trong khi phần lõi bên trong đã thay đổi.
Rủi ro lớn nhất của lớp facade thường nằm ở giá trị mặc định. Khi định dạng mới có thêm một trường dữ liệu mà định dạng cũ không có, hệ thống buộc phải chọn một giá trị thay thế. Nếu giá trị đó liên quan đến tính cước, chiết khấu, chu kỳ thanh toán hoặc trạng thái dịch vụ, một lựa chọn sai có thể làm lệch tiền mà không ai phát hiện ngay. Lỗi thường chỉ lộ ra khi đối soát cuối kỳ.
Đến đây, spec đã có, adapter đã rõ, chiến lược version API cũng đã được kiểm soát phần nào. Nhưng vẫn còn một câu hỏi quan trọng hơn: ai thật sự nhiệm cho ranh giới tích hợp đó khi có sự cố?
Sở hữu ranh giới tích hợp: cần một người nhiệm thật, không phải một nhóm họp định kỳ
Tôi từng tham gia nhiều buổi họp điều phối tích hợp diễn ra hàng tháng, nhưng cuối cùng không ai thực sự quyết được gì. Lý do khá đơn giản: ranh giới tích hợp không thể vận hành bằng trách nhiệm chia đều. Nó cần một người cụ thể nhiệm, có quyền quyết định và theo đến cùng khi sự cố xảy ra.
Người đó phải hiểu luồng nghiệp vụ, hiểu các tình huống lỗi có thể xảy ra và hiểu hệ thống đang chạy thật ngoài vận hành. Trong thực tế, vai trò này thường là Solution Architect hoặc Tech Lead đã làm đủ lâu với vận hành, không chỉ thiết kế trên sơ đồ.
Tôi thường dùng một phép thử rất đơn giản: nếu hệ thống A trả lỗi ở bước 3, hệ thống B phải làm gì? Nếu không ai trả lời được, nghĩa là ranh giới tích hợp đó chưa có người sở hữu thật sự.
Từ các tình huống này, tôi thường rút về một số nguyên tắc thực dụng khi đánh giá hoặc triển khai TMF API. Bảy nguyên tắc tôi rút ra sau nhiều dự án Telco
-
Ranh giới tích hợp nên đi theo luồng nghiệp vụ, không theo từng hệ thống riêng lẻ.
-
Mỗi hệ chỉ nên cung cấp API để kết nối, không truy cập trực tiếp vào cơ sở dữ liệu của nhau.
-
TMF API giúp giảm đáng kể công sức tích hợp, nhưng không thay thế được lớp chuyển đổi dữ liệu, kiểm thử và xác minh hành vi thực tế.
-
Adapter chỉ nên làm nhiệm vụ chuyển đổi dữ liệu và giao tiếp kỹ thuật, không nên chứa logic nghiệp vụ.
-
Các trường như correlationId hay externalId có thể không bắt buộc trong tài liệu đặc tả, nhưng trong vận hành thực tế thì gần như bắt buộc nếu muốn truy vết giao dịch xuyên hệ thống.
-
Các giá trị mặc định ở lớp chuyển đổi cần được rà soát rất kỹ với đội tính cước, vì đây là nơi sai lệch tiền thường xuất hiện âm thầm nhất.
-
Phải có một người thực sự nhiệm cho từng luồng tích hợp. Không phải một nhóm cùng họp rồi chia trách nhiệm chung chung.
Chuẩn hoá luôn có chi phí. Chi phí nâng cấp hệ thống cũ, thời gian triển khai ban đầu lâu hơn và đôi khi là áp lực kinh doanh không chờ được. Nhưng không chuẩn hoá cũng có giá của nó. Không có chuẩn chung thì cuối cùng mỗi đội sẽ làm theo một kiểu riêng. Khi cần tích hợp lại, tiếp quản phân hệ, thay nhà cung cấp hoặc mở rộng sang thị trường khác, đội ngũ phải tìm hiểu lại từ đầu, mapping lại dữ liệu và API, rồi trả giá ở vận hành.
Đi nhanh luôn có cái giá của đi nhanh. Vấn đề là chọn trả giá ở giai đoạn thiết kế hay trả giá về sau trong vận hành.
Checklist khi triển khai TMF API
Dùng khi đánh giá phạm vi áp dụng TMF API hoặc khi chuẩn bị tích hợp với nhà cung cấp mới.
A. Ranh giới tích hợp
-
[ ] Mỗi hệ thống chỉ expose API, không cho hệ khác truy cập trực tiếp DB?
-
[ ] Ranh giới define theo journey hay theo từng hệ riêng lẻ?
-
[ ] Có correlationId/externalId xuyên suốt journey không?
B. TMF compliance thực tế
-
[ ] Core payload giữ đúng TMF spec, hay chỉ giữ endpoint path?
-
[ ] Nghiệp vụ riêng nằm trong extension attribute hay viết đè lên core fields?
-
[ ] Khi vendor claim TMF compliant, đã verify data model và behavior thực tế chưa?
C. Adapter
-
[ ] Adapter chỉ dịch, hay đang chứa if-else nghiệp vụ?
-
[ ] Khi vendor upgrade, ai cập nhật adapter và trong bao lâu?
D. Versioning
-
[ ] Chiến lược backward compatibility là gì (chạy song song, header-based, lớp dịch)?
-
[ ] Có sunset policy cho version cũ không, hay đang ở N-3/N-4?
-
[ ] Khi nâng API mà đối tác ngoài không nâng cùng, có facade không, ai maintain?
-
[ ] Giá trị mặc định ở lớp dịch/facade đã review với đội billing chưa?
E. Người nhiệm
-
[ ] Có một người cụ thể nhiệm ranh giới tích hợp từng journey không?
-
[ ] Người đó trả lời được: hệ A lỗi bước 3, hệ B làm gì?
Kết lại
TMF API là một chuẩn rất hữu ích nhưng nó chỉ thực sự có giá trị khi được dùng như một hợp đồng vận hành giữa các hệ thống, không phải chỉ để làm đẹp sơ đồ kiến trúc.
Cái khó nhất của tích hợp Telco nằm ở chỗ các hệ thống có thực sự hiểu cùng một luồng nghiệp vụ hay không, có truy vết được giao dịch từ đầu đến cuối hay không và khi mọi thứ lệch nhau thì ai là người nhiệm.
Cùng theo dõi BiPlus để đón chờ các bài tiếp theo trong series Inside Telco Systems.
Về tác giả

Quoc Dinh – Co-founder | Phó Giám đốc
Bạn có một ý tưởng phần mềm nhưng chưa biết nên bắt đầu từ đâu, cũng không chắc phải làm thế nào để hiện thực hóa nó. Đây là giai đoạn then chốt, bởi chỉ cần đưa ra những quyết định sai ngay từ đầu, cả doanh nghiệp có thể bị ảnh hưởng nghiêm trọng.
Vì vậy, hãy để tôi đồng hành cùng bạn. Tôi có hơn chín năm kinh nghiệm làm Software Development Engineer, chuyên phát triển, nâng cấp và triển khai các hệ thống phần mềm trong ngành viễn thông, đặc biệt là mảng BCCS (Billing, Charging and Customer Care System). Ngoài ra, tôi cũng đã có hơn hai năm làm việc tại thị trường quốc tế, trong đó có Peru.
“Quoc là một Tech PM vừa có trách nhiệm vừa có năng lực. Anh ấy rất thành thạo các dự án Samsung 3PD và luôn là người đầu tiên mọi người nghĩ đến khi gặp sự cố. Được làm việc cùng anh ấy thật sự rất thoải mái.”
— Mr. Minsu Jang, PMO Consultant tại S-Core.
Bạn đã sẵn sàng sở hữu sản phẩm phần mềm đột phá tiếp theo chưa? Let’s connect!









