[GraphQL] Bài 1: GraphQL là gì?

GraphQL là một tiêu chuẩn API mới cung cấp một giải pháp thay thế hiệu quả, mạnh mẽ và linh hoạt hơn REST. Ban đầu GraphQL được Facebook phát triển và hiện là một open-source đang được một một cộng đồng lớn bao gồm các công ty và các cá nhân trên khắp thế giới chung tay xây dựng.

Như ta đã biết hiện tại API đã trở thành các thành phần phổ biến của cơ sở hạ tầng phần mềm. Một API định nghĩa cách client có thể tải dữ liệu từ server và GraphQL cho phép client có thể định nghĩa chính xác dữ liệu nào nó cần từ một API. Thay vì cần nhiều endpoint mà mỗi endpoint trả về một cấu trúc dữ liệu cố định, GraphQL server chỉ cần một endpoint duy nhất và phản hồi chính xác dữ liệu mà client yêu cầu.

GraphQL - ngôn ngữ truy vấn cho API

Hầu hết các ứng dụng ngày nay đều có nhu cầu tải dữ liệu từ một server (được lưu trữ trong cơ sở dữ liệu của server đó). Nhiệm vụ của API là cung cấp interface tới dữ liệu được lưu trữ phù hợp với nhu cầu của ứng dụng.

GraphQL thường bị nhầm lẫn là một kỹ thuật liên quan đến cơ sở dữ liệu. Đây là một quan niệm sai lầm, GraphQL là một ngôn ngữ truy vấn cho các API - chứ không phải cho cơ sở dữ liệu. Nó không phụ thuộc vào cơ sở dữ liệu và có thể hoạt động một cách hiệu quả trong mọi ngữ cảnh có sử dụng API.

Sự hạn chế của REST

REST là một cách phổ biến để lấy dữ liệu từ một server. Khi REST được phát triển, các ứng dụng client tương đối đơn giản và tốc độ phát triển không nhanh như ngày nay. Do vậy khi đó REST phù hợp cho nhiều ứng dụng. Tuy nhiên, bối cảnh về API đã thay đổi hoàn toàn trong vài năm qua. Đặc biệt, có ba yếu tố thách thức việc thiết kế API:

  1. Sự bùng nổ của thiết bị di động
    Các thiết bị di động yếu hơn máy tính cá nhân, bị giới hạn bởi dung lượng pin và kết nối mạng băng thông kém và thiếu ổn định. Do đó nó đòi hỏi một phương thức truyền tải dữ liệu hiệu quả. Và việc số lượng người dùng Facebook qua thiết bị di động ngày càng tăng khiến Facebook phải phát triển GraphQL. GraphQL giảm thiểu lượng dữ liệu cần truyền qua mạng nên cải thiện đáng kể hiệu năng của các ứng dụng di động.

  2. Sự đa dạng của các platform và framework
    Sự không đồng nhất của các platform và framework chạy các ứng dụng client khiến cho việc xây dựng và bảo trì một API phù hợp với yêu cầu của tất cả mọi platform, framework trở nên khó khăn. Với GraphQL, mỗi client có thể truy cập chính xác dữ liệu mà nó cần.

  3. Xu hướng phát triển phần mềm nhanh và liên tục
    Phương pháp phát triển phần mềm liên tục đã trở thành một tiêu chuẩn của nhiều công ty. Các vòng đời phát triển phần mềm nhanh chóng, các bản cập nhật liên tục được đưa ra. Với các API REST, cách dữ liệu được server trả về thường xuyên cần phải sửa đổi để phù hợp các yêu cầu cụ thể và các thay đổi thiết kế ở phía client. Điều này đã cản trở, làm chậm lại tốc độ phát triển phần mềm một cách đáng kể.

GraphQL - sự thay thế cho REST

GraphQL được phát triển để đáp ứng nhu cầu một cách linh hoạt và hiệu quả hơn! Nó giải quyết được nhiều thiếu sót và sự 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 API REST.

Để minh họa sự khác biệt chính giữa REST và GraphQL khi lấy dữ liệu từ API, hãy xem xét một trường hợp ví dụ đơn giản: Trong ứng dụng viết blog, ứng dụng cần:

  • Hiển thị tiêu đề của tất cả các bài đăng của một người dùng cụ thể.
  • Cùng trên màn hình đó, hiển thị tên của 3 người theo dõi cuối cùng của người dùng đó.

Tình huống đó sẽ được giải quyết như thế nào với REST và GraphQL?

Với một API REST, bạn thường sẽ lấy dữ liệu bằng cách truy cập tới nhiều endpoint. Trong ví dụ này, các endpoint có thể là:

  • /users/<id>: dữ liệu người dùng ban đầu.
  • /users/<id>/posts: danh sách các bài đăng của người dùng đó
  • /users/<id>/followers: danh sách người theo dõi trên mỗi người dùng.

Ta có thể thấy, với REST API, client phải gọi đến 3 endpoint để lấy được dữ liệu cần thiết. Bên cạnh đó, ngoài dữ liệu cần thiết để hiển thị, server còn trả về nhiều dữ liệu dư thừa gây lãng phí tài nguyên hệ thống.

Không còn thừa hay thiếu dữ liệu

Một trong những vấn đề phổ biến nhất với REST là sự dư thừa cũng như thiếu hụt dữ liệu. Điều này xảy ra vì cách duy nhất để client lấy dữ liệu là gọi đến endpoint và server trả về dữ liệu với cấu trúc cố định. Rất khó để thiết kế API theo cách có thể cung cấp cho client những dữ liệu chính xác với nhu cầu của tất cả các client.

  • Sự dư thừa xảy ra khi một client phải tải xuống nhiều thông tin hơn so với nhu cầu thực sự của nó. Ví dụ một màn hình cần hiển thị danh sách người dùng chỉ với tên của họ. Trong một API REST, ứng dụng này thường sẽ truy cập điểm cuối /users và nhận một đối tượng JSON với dữ liệu các người dùng. Tuy nhiên, kết quả có thể chứa thêm thông tin về người dùng được trả về, ví dụ: ngày sinh nhật hoặc địa chỉ của họ. Tại sao server phải trả về nhiều thông tin dư thừa như vậy? Đó là do API phải được thiết để đáp ứng được nhiều yêu cầu của của nhiều client, ví dụ ở màn hình thông tin chi tiết của người dùng cần hiển thị cả địa chỉ và ngày sinh nhật.

  • Sự thiếu hụt dữ liệu xảy ra khi server không cung cấp đủ thông tin cần thiết trong một endpoint. Client sẽ phải gọi đến các endpoint bổ sung để lấy những dữ liệu còn thiếu. Điều này có thể dẫn đến tình huống mà client phải tải xuống một danh sách các phần tử, và tiếp đó phải gọi thêm endpoint cho mỗi phần tử để lấy thêm những dữ liệu cần thiết.
    Ví dụ: ở ứng dụng blog trên, cần hiển thị ba người theo dõi cuối cùng cho mỗi người dùng. Để có thể hiển thị thông tin được yêu cầu, ứng dụng sẽ phải gọi tới endpoint /users và sau đó gọi tới endpoint /users/<user-id>/followers cho mỗi người dùng.

Với GraphQL, client chỉ cần gửi một câu truy vấn tới GraphQL server xác định rõ những dữ liệu cần thiết. Và server sau đó sẽ trả về cho client một đối tượng JSON chỉ chứa những dữ liệu mà client đã yêu cầu.

Phát triển cập nhật frontend nhanh chóng

Một pattern chung cho REST API là việc thiết kế cấu trúc các endpoint theo các view bên 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 tất cả các thông tin cần thiết cho một view cụ thể bằng cách truy cập vào endpoint tương ứng.
Tuy nhiên hạn chế của cấu trúc này là nó không cho phép một sự thay đổi nhanh trên frontend. Mọi thay đổi về frontend đều có khả năng cao dẫn đến sự thay đổi lượng dữ liệu cần thiết (nhiều hơn hoặc ít hơn). Do đó, phía backend cũng cần được điều chỉnh để đáp ứng các nhu cầu dữ liệu mới. Điều này làm giảm năng suất và làm chậm sự kết hợp 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, client có thể chỉ định chính xác và cụ thể các yêu cầu về dữ liệu, phía backend không cần phải thay đổi gì khi phía frontend thay đổi về thiết kế và dữ liệu cần lấy về.

Khả năng phân tích nhu cầu về dữ liệu

Vì với GraphQL, mỗi client chỉ định chính xác thông tin mà nó cần nên ta có thể nắm được thông tin chi tiết về cách mà dữ liệu sẵn có đang được sử dụng. Dựa vào những thông tin này, ta có thể cải tiến các API, ví dụ bỏ đi các trường dữ liệu không được bất kỳ client nào yêu cầu.

Thêm vào đó, ta cũng có thể thực hiện giám sát hiệu năng xử lý request từ client của server. GraphQL sử dụng khái niệm về resolver function để thu thập dữ liệu được yêu cầu từ client. Việc đo lường và đánh giá hiệu suất của các resolver này cung cấp thông tin chi tiết quan trọng về các bottleneck trong hệ thống.

Lợi ích của Schema & Type

GraphQL sử dụng một hệ thống strong type để định nghĩa khả năng của một API. Tất cả các kiểu dữ liệu trong một API được định nghĩa trong một schema bằng SDL (Schema Definition Language) của GraphQL. Schema này đóng vai trò là quy ước giữa client và server xác định cách mà client có thể truy cập dữ liệu.

Sau khi schema đượ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 mình mà không cần liên lạc thêm vì cả hai đều biết cấu trúc xác định 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 các cấu trúc dữ liệu cần thiết được trả về. Khi server đã sẵn sàng, các ứng dụng client có thể ngay lập tức chuyển sang sử dụng API thực tế được cung cấp bởi server.

Kết luận

Qua bài viết chúng ta đã nắm được GraphQL là một ngôn ngữ truy vấn dành cho API, giúp cho client có thể định nghĩa chính xác các nhu cầu về dữ liệu và server chỉ trả về client những dữ liệu mà client đã yêu cầu. Thêm vào đó chúng ta cũng nắm được những hạn chế của REST API hiện nay và những lợi ích mà GraphQL mang lại. Trong bài viết tiếp theo chúng ta hãy cũng tìm hiểu những khái niệm cơ bản được sử dụng trong GraphQL.

Tài liệu tham khảo

Internet :)

Enso.