GraphQL tốt hơn REST
Trong thập kỷ qua, REST đã trở thành tiêu chuẩn để thiết kế Web API. Nó cung cấp một số ý tưởng tuyệt vời, chẳng hạn như máy chủ không trạng thái và truy cập tài nguyên có cấu trúc.
Tuy nhiên, REST API đã được chứng minh là rất không linh hoạt để theo kịp các yêu cầu thay đổi nhanh chóng của các client (máy khách) truy cập chúng.
GraphQL được phát triển để đáp ứng nhu cầu linh hoạt và hiệu quả hơn. Nó giải quyết được những thiếu sót và thiếu hiệu quả mà các nhà phát triển gặp phải khi làm việc với các REST API.
Để minh họa sự khác biệt chính giữa REST và GraphQL khi lấy dữ liệu từ API, chúng ta hãy xem xét ví dụ về một ứng dụng viết blog đơn giản sau:
- Trong ứng dụng có một màn hình hiển thị thông tin của một người dụng cụ thể và tiêu đề của các bài đăng của người dùng đó.
- Màn hình này cũng hiển thị tên của 3 người theo dõi gần đây nhất của người dùng đó.
Tình huống đó sẽ được giải quyết như thế nào khi sử dụng REST và GraphQL? Chúng ta sẽ làm rõ ở ngay phía dưới.
💡 Hãy xem bài viết này để tìm hiểu thêm về lý do tại sao các nhà phát triển yêu GraphQL.
Lấy dữ liệu sử dụng REST vs GraphQL
Với REST, bạn thường lấy dữ liệu bằng cách truy cập nhiều API. Đầu tiên bạn sẽ truy cập API /users/<id>
để lấy dữ liệu người dùng.
Tiếp theo, bạn sẽ truy cập API /users/<id>/posts
để lấy tất cả các bài đăng cho người dùng này.
Cuối cùng bạn sẽ truy cập API /users/<id>/followers
để lấy danh sách người theo dõi cho người dùng này.
Với GraphQL, bạn chỉ cần gửi một truy vấn đến máy chủ GraphQL bao gồm các yêu cầu dữ liệu cụ thể. Sau đó, máy chủ trả về một đối tượng JSON đáp ứng đầy đủ các yêu cầu của bạn.
Không còn tải quá nhiều và tải quá ít
Các lập trình viên thường nói đến lợi ích chính của GraphQL là client có thể lấy chính xác dữ liệu họ cần từ API.
Họ không phải phụ thuộc vào các cấu trúc dữ liệu cố định và được định nghĩa trước do REST trả về. Thay vào đó, client có thể khai báo cấu trúc dữ liệu của các đối tượng được API trả về.
Điều này giải quyết hai vấn đề thường gặp với REST API là: tải quá nhiều và tải quá ít.
Với GraphQL, client hoàn toàn có thể khai báo cấu trúc dữ liệu của các đối tượng được API trả về.
Vấn đề tải quá nhiều của REST API
Tải quá nhiều có nghĩa là client tải những dữ liệu không thực sự cần thiết. Do đó, nó làm giảm hiệu suất của ứng dụng (cần nhiều thời gian hơn để tải dữ liệu và phân tích cú pháp) và nó cũng làm cạn kiệt gói dữ liệu của người dùng (ví dụ: 3G hoặc 4G).
Một ví dụ đơn giản cho việc tải quá nhiều là tình huống sau: Ứng dụng hiển thị thông tin tên và ngày sinh trong màn hình hồ sơ của người dùng.
Tuy nhiên API tương ứng cung cấp thông tin về người dùng trả về thêm thông tin địa chỉ và thông tin thanh toán.
Cả hai thông tin này đều vô dụng đối với màn hình hồ sơ và do đó việc tải chúng là không cần thiết.
Vấn đề tải quá ít của REST API
Tải quá ít thì ngược lại với tải quá nhiều, nó có nghĩa là API không trả về đủ dữ liệu theo yêu cầu. Điều này có nghĩa là client cần phải gọi thêm các API khác để bổ sung dữ liệu cho yêu cầu.
Trong trường hợp xấu nhất là khi client yêu cầu thông tin về một danh sách với n
phần tử. Tuy nhiên, không có API nào thỏa mãn yêu cầu dữ liệu. Thay vào đó, client cần gọi thêm API khác để bổ sung dữ liệu cho mỗi phần tử trong danh sách.
Ví dụ, chúng ta tiếp tục lấy ví dụ với ứng dụng viết blog ở trên. Ứng dụng hiển thị danh sách người dùng, trong đó mỗi người dùng sẽ hiển thị kèm theo tiêu đề bài viết mới được xuất bản bởi người dùng đó.
Tuy nhiên, phần thông tin đó không có trong API trả về danh sách người dùng. Do đó ứng dụng phải gọi thêm API để lấy thông tin bài viết mới nhất cho từng người dùng trong danh sách.
Lưu ý: Với REST API, các vấn đề về tải quá ít và quá nhiều thường được giải quyết bằng cách thay đổi dữ liệu trả về của API (thay đổi backend) theo nhu cầu của client. Như ví dụ trên thì chúng ta sẽ bổ sung tiêu đề của bài viết mới nhất của mỗi người dùng vào API trả về danh sách người dùng. Cách tiếp cận này ban đầu có vẻ như là một giải pháp tốt, nhưng nó cản trở các chu kỳ phát triển và lặp lại sản phẩm nhanh bởi vì bất kỳ thiết kế lại nào của ứng dụng thường sẽ yêu cầu thay đổi backend tốn nhiều thời gian hơn.
Vòng lặp phát triển sản phẩm nhanh chóng trên Frontend
Một mô hình phổ biến với REST là cấu trúc dữ liệu của các API được thiết kế cố định cho các màn hình mà bạn có trong ứng dụng của mình.
Điều này rất tiện lợi vì nó cho phép client nhận được tất cả thông tin cần thiết cho một một màn hình cụ thể bằng cách truy cập vào API tương ứng.
Hạn chế chính của phương pháp này là nó không cho phép lặp lại nhanh chóng trên frontend. Với mỗi thay đổi được thực hiện cho UI, có một rủi ro cao là sẽ có nhiều hơn (hoặc ít hơn) dữ liệu được yêu cầu so với trước.
Do đó, backend cũng cần được điều chỉnh để đáp ứng nhu cầu dữ liệu của frontend. Điều này làm giảm năng suất và làm chậm khả năng áp dụng các phản hồi của người dùng vào sản phẩm.
Với GraphQL, vấn đề này đã được giải quyết. Nhờ tính chất linh hoạt của GraphQL, các thay đổi ở phía máy khách có thể được thực hiện mà không cần thêm bất kỳ công việc nào trên máy chủ.
Vì máy khách có thể chỉ định các yêu cầu dữ liệu chính xác nên không cần phải điều chỉnh lại backend khi frontend thay đổi thiết kế và dữ liệu đầu vào.
Phân tích sâu sắc về backend
GraphQL cho phép bạn có những hiểu biết chi tiết về dữ liệu được yêu cầu phía backend. Vì mỗi máy khách chỉ định chính xác thông tin mà họ quan tâm, nên có thể hiểu sâu về cách sử dụng dữ liệu hiện có.
Điều này có thể giúp phát triển API và loại bỏ các trường cụ thể không còn được yêu cầu bởi bất kỳ ứng dụng máy khách nào nữa.
Với GraphQL, bạn cũng có thể thực hiện giám sát hiệu suất cấp thấp đối với các yêu cầu được xử lý bởi máy chủ của bạn.
GraphQL sử dụng khái niệm về các trình phân giải để thu thập dữ liệu mà khách hàng yêu cầu.
Các trình phân giải này cung cấp những hiểu biết quan trọng về các tắc nghẽn trong hệ thống của bạn.
Lợi ích của lược đồ và định kiểu trong GraphQL
GraphQL sử dụng một hệ thống định kiểu mạnh để định nghĩa các chức năng của API. Tất cả các kiểu dữ liệu được hiển thị trong API được ghi lại trong một lược đồ sử dụng ngôn ngữ định nghĩa lược đồ đồ thị (SDL).
Lược đồ này đóng vai trò là hợp đồng (contract) giữa máy khách và máy chủ để xác định cách máy khách có thể truy cập dữ liệu.
Khi lược đồ được định nghĩa, các nhóm làm việc trên frontend và backend có thể thực hiện công việc của họ mà không cần liên lạc thêm vì cả hai đều biết được cấu trúc của dữ liệu được gửi qua mạng.
Các nhóm frontend có thể dễ dàng kiểm tra các ứng dụng của họ bằng cách giả lập (mock) các cấu trúc dữ liệu cần thiết. Khi máy chủ đã sẵn sàng, có thể dễ dàng chuyển các ứng dụng khách sang sử dụng dữ liệu trực tiếp từ API thực tế.
Ở hướng dẫn tiếp theo bạn sẽ tìm hiểu các khái niệm cốt lõi của GraphQL như: Query, Mutation, Subscription và cách sử dụng chúng để định nghĩa lược đồ (schema) trong GraphQL.