API – Application Programming Interface hay Giao diện lập trình ứng dụng, là một tập hợp các định nghĩa và giao thức cho phép các ứng dụng phần mềm giao tiếp và tương tác với nhau. User Interface (Giao diện người dùng) là nơi mà người dùng sẽ tương tác với ứng dụng, tương tự như thế khi các ứng dụng tương tác với nhau cũng cần thông qua giao diện đặc biệt, giao diện đó có tên gọi là API.
1. API là gì?
Application Programming Interface là một tập hợp các định nghĩa và giao thức cho phép các ứng dụng phần mềm giao tiếp và tương tác với nhau. Thông qua API các phần mềm ứng dụng có thể giao tiếp, trao đổi dữ liệu theo dạng Request-Response với nhau bằng một tập hợp các định nghĩa và giao thức.
Ví dụ: Công ty của bạn đang xây dựng một ứng dụng quản lý cửa hàng, ứng dụng này được tạo thành từ nhiều Dịch vụ (Service) khác nhau như: Quản lý người dùng, đơn hàng, thanh toán, … Khi khách hàng thanh toán, dịch vụ Quản lý thanh toán sẽ giao tiếp với dịch vụ Quản lý đơn hàng để cập nhật trạng thái đơn hàng (thanh toán thành công/thất bại), nói một cách khác Payment Service sẽ gọi API của Order Service để cập nhật Order Status.
2. API hoạt động như thế nào?
Kiến trúc API thường được giải thích dưới dạng máy chủ và máy khách. Ứng dụng gửi yêu cầu được gọi là máy khách, còn ứng dụng gửi phản hồi được gọi là máy chủ. Như vậy, trong ví dụ về thời tiết, cơ sở dữ liệu của cơ quan thời tiết là máy chủ còn ứng dụng di động là máy khách. API hoạt động theo 4 cách khác nhau, tùy vào thời điểm và lý do chúng được tạo ra.
3. Các giao thức API phổ biến (API Protocol)
Công nghệ API liên tục thay đổi và phát triển mỗi ngày, nên việc giao thức này trở thanh xu hướng rôi trôi vào ghẻ lạnh và quên lãng trong cộng đồng là chuyện hết sức bình thường. Hãy cùng Imtech tìm hiểu về một số giao thức API phổ biến nhất hiện nay
3.1 REST – Representational State Transfer
REST – Representational State Transfer, là một kiến trúc định nghĩa tiêu chuẩn giao tiếp giữa các hệ thống Web (Web API). Các hệ thống tuân thủ tiêu chuẩn REST thường được gọi là RESTful, có 6 nguyên tắc mà bạn sẽ phải tuân thủ:
Client-Server: REST tách biệt vai trò của máy khách (client) và máy chủ (server). Máy khách chịu trách nhiệm gửi yêu cầu, trong khi máy chủ xử lý yêu cầu và trả về phản hồi. Điều này giúp phân chia trách nhiệm rõ ràng và cho phép phát triển từng thành phần độc lập.
Stateless: REST tuân thủ nguyên tắc không trạng thái, nghĩa là mỗi yêu cầu từ máy khách đến máy chủ phải chứa tất cả thông tin cần thiết để hiểu và xử lý yêu cầu. Máy chủ không lưu trữ trạng thái của máy khách giữa các yêu cầu, giúp hệ thống dễ mở rộng và bảo trì hơn.
Cacheable: Các phản hồi từ máy chủ có thể được gắn cờ để lưu trữ ở bộ nhớ đệm (cache) nếu thích hợp, giúp giảm tải cho máy chủ và cải thiện hiệu suất hệ thống.
Uniform Interface: REST sử dụng một giao diện đồng nhất để tương tác với các tài nguyên (resource). Giao diện này thường sử dụng các phương thức HTTP tiêu chuẩn như GET, POST, PUT, DELETE, v.v., và các URIs để xác định tài nguyên.
Layered System: REST cho phép kiến trúc hệ thống được xây dựng thành các lớp, trong đó mỗi lớp có thể thực hiện một nhiệm vụ cụ thể mà không cần biết về các lớp khác. Điều này giúp tăng tính linh hoạt và khả năng mở rộng của hệ thống.
Code on Demand: REST có thể hỗ trợ tuỳ chọn tải thêm các tính năng về khi Client yêu cầu (khi người dùng click vào) mà không phải tải hết một lần khi bạn mở ứng dụng.
Thông qua các động từ HTTP khác nhau, Client có thể tương tác với một tài nguyên như sau:
- GET /customers: Lấy danh sách các khách hàng
- GET /customer/{id}: Lấy thông tin chi tiết của một khách hàng bằng cách sử dụng mã định danh của họ.
- POST /customers: Khởi tạo khách hàng mới.
- PUT /customers/{id}: Sửa đổi một khách hàng hiện có được xác định bởi ID của họ.
- DELETE /customers/{id}: Xóa một khách hàng bằng ID của họ.
3.2 Webhook
Webhook là một cơ chế cho phép một ứng dụng cung cấp dữ liệu theo thời gian thực cho các ứng dụng khác khi có sự kiện xảy ra. Thay vì yêu cầu liên tục từ client (pulling) để kiểm tra xem có sự kiện mới hay không, webhook sẽ gửi dữ liệu đến một URL cụ thể khi sự kiện đó xảy ra, thường được gọi là “callback URL” hoặc endpoint.
3.3 GraphQL
GraphQL không phải là một ngôn ngữ lập trình mà là một ngôn ngữ truy vấn, giúp định nghĩa các tác vụ như query (truy vấn), mutation (thay đổi) hay subscription (lắng nghe thay đổi) trên một GraphQL Server. GraphQL được thiết kế với các nguyên tắc sau đây:
Hierarchical: Truy vấn GraphQL sẽ phản ánh mối quan hệ phân cấp, ví dụ: một người dùng có thể có nhiều bài viết, và mỗi bài viết có thể có nhiều bình luận.
View-centric: Thay vì API quyết định những gì cần trả về, client quyết định họ cần dữ liệu gì và truy vấn GraphQL sẽ phản ánh điều đó.
Strongly-typed: Mỗi trường và đối tượng trong GraphQL đều có một kiểu dữ liệu xác định rõ ràng, điều này giúp đảm bảo rằng các truy vấn được thực hiện chính xác và các lỗi có thể được phát hiện sớm
Client-driven: Trong GraphQL, client hoàn toàn kiểm soát những dữ liệu mà họ cần bằng cách xác định các trường cụ thể trong truy vấn. Điều này khác với REST, nơi mà server quyết định những gì sẽ được trả về.
Introspective: GraphQL có tính năng introspection, cho phép client tự động khám phá schema của API. Client có thể gửi các truy vấn introspection để biết được các kiểu dữ liệu, các trường có sẵn, và các mối quan hệ trong schema của API.
Version-free: Một trong những nguyên tắc chính của GraphQL là không cần phải duy trì nhiều phiên bản của API. Bởi vì client có thể yêu cầu chính xác dữ liệu họ cần, bạn có thể phát triển và mở rộng API mà không phá vỡ tính tương thích với các client cũ.
3.4 gRPC
Giống các giao thức RPC khác, gRPC (gRPC Remote Procedure Calls) bao gồm một máy chủ (server) định nghĩa các phương thức có thể được gọi từ xa bởi các máy khách (clients). Để đạt được điều này, gRPC giới thiệu khái niệm gRPC client stubs và gRPC servers. Một tính năng quan trọng của gRPC và là một trong những lý do chính khiến nó trở nên phổ biến trong các kiến trúc microservice, là khả năng hỗ trợ bốn kiểu tương tác sau đây:
Unary: gRPC hỗ trợ mô hình Request/Response truyền thống, giúp dễ dàng tích hợp với các hệ thống hiện có sử dụng RPC. Điều này giống với việc bạn yêu cầu thông tin của 100 khách hàng và hệ thống sẽ trả về cho bạn 100 khách hàng, sau đó yêu cầu sẽ được đóng lại.
Server streaming: gRPC cho phép máy chủ gửi một luồng dữ liệu liên tục đến máy khách sau khi nhận được yêu cầu, phù hợp với các trường hợp cần truyền dữ liệu theo thời gian thực hoặc khối lượng lớn. Tưởng tượng là bạn đang mở ứng dụng Netflix và chọn xem một bộ phim có nhiều tập với gRPC, Netflix Server gửi một luồng dữ liệu liên tục (các tập phim) đến bạn sau khi bạn đã yêu cầu xem bộ phim. Với REST hay RPC thông thường, sau khi xem xong tập đầu tiên, nếu bạn muốn xem tiếp tập thứ hai, bạn sẽ phải gửi một yêu cầu GET khác đến API để lấy tập tiếp theo. Các bạn có thể đọc thêm về lợi ích của gRPC khi triển khai Microservice.
Client streaming: Máy khách có thể gửi một chuỗi các thông điệp đến máy chủ trước khi nhận được phản hồi (ngược lại với ví dụ ở mục 2).
Bidirectional streaming: gRPC cho phép giao tiếp hai chiều không đồng bộ giữa máy khách và máy chủ, giúp cả hai có thể trao đổi dữ liệu liên tục và đồng thời, làm tăng tính linh hoạt và hiệu quả trong các ứng dụng cần giao tiếp phức tạp.