TÌm hiểu về GraphQL

Việc áp dụng GraphQL ngày càng nhiều như việc các công ty Facebook, GitHub và Pinterest sử dụng trong các ứng dụng của họ, và rất nhiều developer đã chuyển sang GraphQL vì những tính năng tuyệt vời mà nó cung cấp. Bài viết này sẽ giúp bạn hiểu về GraphQL.

GraphQL là gì?

GraphQL là một ngôn ngữ truy vấn cho API, cung cấp một mô tả hoàn chỉnh cho dữ liệu trong API của bạn, cho phép phía client yêu cầu chính xác dữ liệu cần thiết mà không bị thừa hay thiếu. Nói cách khác, nó cung cấp một interface chung giữa client và server cho việc lấy và thao tác với dữ liệu.

Từ cái tên GraphQL, bạn có thể nghĩ rằng GraphQL liên quan đến graph database hay SQL. Thực tế GraphQL không liên quan gì đến data storage hay graph database.

Để hiểu hơn về GraphQL là gì, hãy xem những tiện ích mà nó cung cấp:

  • Declarative: Với GraphQL, bạn tự định nghĩa ra những dữ liệu bạn cần.
  • Hierarchical: Với mỗi request, bạn có thể lấy được một object và cả những object liên quan với object đó, ví dụ một Author cùng với các Posts mà người đó tạo ra, mà các Comments trên mỗi Post.
  • Strongly-typed: Với hệ thống GraphQL, ta có thể mô tả dữ liệu có thể truy vấn từ server dựa trên kiểu của object và dữ liệu trả về sẽ phù hợp với kiểu object chỉ định trong câu truy vấn.
  • Not Language specific:** GraphQL không gắn với một ngôn ngữ lập trình cụ thể nào cả.
  • Compatible with any backend: GraphQL không bị giới hạn bởi một data storage cụ thể; bạn có thể sử dụng data và code có sẵn, kể cả kết nối đến third-party APIs.
  • Introspective: một GraphQL server có thể được truy vấn về schema cụ thể của nó.

Thêm vào đó, GraphQL rất để sử dụng vì nó có cú pháp giống JSON và cho rất nhiều lợi ích về performance.

Tiếp theo, ta sẽ đi tìm hiểu về cú pháp và các hoạt động có thể thực thi với GraphQL.

Query

Query được sử dụng để thực thi hành động đọc, lấy dữ liệu từ server. Dưới đây là một ví dụ về một query đơn giản và response tương ứng:

# Query

    query GetAuthor {
      author {
        name
        posts {
          title
        }
      }
    }
 # Response

    {
      "data": {
        "author": {
          "name": "Chimezie Enyinnaya",
          "posts": [
            {
              "title": "How to build a collaborative note app using Laravel"
            },
            {
              "title": "Event-Driven Laravel Applications"
            }
          ]
        }
      }
    }

Đây là một query đơn giản để lấy name của một author cùng với các posts tương ứng của author đó. Chú ý rằng query và response có cấu trúc giống nhau. Bây giờ ta sẽ tìm hiểu về các thành phần của một GraphQL query. Ở câu query trên, ta có thể không dùng từ khóa query. Nếu một operation không chỉ định type thì mặc định GraphQL sẽ cho rằng operation đó là một query. Một query có thể có tên (GetAuthor). Mặc dù tên của query có thể có hoặc không nhưng nó sẽ giúp dễ hiểu query đó dùng để làm gì.

Fields

fields là thành phần cơ bản của một object mà ta muốn thu được từ server. Ở câu query trên, name là một field của author

Arguments

Một query có thể nhận tham số truyền vào.

{
      author(id: 5) {
        name
      }
    }

Variables

Bên cạnh tham số, một query cũng có thể có các biến. Các biến được đặt trước bởi dấu $ và theo sau là kiểu của nó.

query GetAuthor($authorID: Int!) {
      author(id: $authorID) {
        name
      }
    }

Một biến cũng có thể có giá trị mặc định của nó.

 query GetAuthor($authorID: Int! = 5) {
      author(id: $authorID) {
        name
      }
    }

Giống với tham số, biến cũng có thể là tùy chọn hoặc bắt buộc. Ở ví dụ trên $authorID là bắt buộc vì sử dụng ký hiệu ! khi định nghĩa biến.

Aliases

Để request dữ liệu từ cùng một field với các tham số khác nhau, ta sử dụng aliases

 {
      chimezie: author(id: 5) {
        name
      }
      neo: author(id: 7) {
        name
      }
    }

Và response sẽ có dạng

{
      "data": {
        "chimezie": {
          "name": "Chimezie Enyinnaya"
        },
        "neo": {
          "name": "Neo Ighodaro"
        }
      }
    }

Fragments

Fragments là một tập hợp các fields có thể sử dụng lại và include vào query khi cần thiết. Ví dụ:

 {
      chimezie: author(id: 5) {
        ...authorDetails
      }
      neo: author(id: 7) {
        ...authorDetails
      }
    }

    fragment authorDetails on Author {
      name
      twitterHandle
    }

Với query trên, khi cần thêm một field nào đó, ta chỉ cần thêm vào fragment.

Directives

Directives cho phép ta thay đổi cấu trúc query một cách linh hoạt sử dụng các biến. GraphQL có 2 directive:

  • @include sẽ include một field hay fragment khi tham số iftrue.
  • @skip sẽ bỏ qua một field hay fragment khi tham số iffalse.

Cả hai directive nhận tham số kiểu boolean.

    query GetAuthor($authorID: Int!, $notOnTwitter: Boolean!, $hasPosts: Post) {
      author(id: $authorID) {
        name
        twitterHandle @skip(if: $notOnTwitter)
        posts @include(if: $hasPosts) {
          title
        }
      }
    }

Mutation

Mutations được sử dụng để thực hiện hành động write.

    mutation UpdateAuthorDetails($authorID: Int!, $twitterHandle: String!) {
      updateAuthor(id: $authorID, twitterHandle: $twitterHandle) {
        twitterHandle
      }
    }

Ta gửi dữ liệu như một payload trong mutation.

{
     "authorID": 5,
     "twitterHandle": "ammezie"
    }

Sau đó server sẽ trả về respone sau khi thực hiện update:

{
      "data": {
        "id": 5,
        "twitterHandle": "ammezie"
      }
    }

Trong response trả về sẽ chữa dữ liệu đã được update.

Một điểm khác biệt quan trọng giữa mutation và query là mutation thực hiện một cách tuần tự còn query có thể thực thi song song.

Schemas

Schemas mô tả cách dữ liệu được tổ chức và những dữ liệu nào có thể được truy vấn. Schemas cung cấp các kiểu object được sử dụng. GraphQL schema quy định kiểu chặt chẽ, mọi object trong schema phải được chỉ định kiểu. Kiểu được sử dụng để xác định một truy vấn có hợp lệ hay không.

Schemas được xây dựng sử dụng GraphQL schema language. Ví dụ:

type Author {
      name: String!
      posts: [Post]
    }

Schema trên định nghĩa một object kiểu Author vơi 2 field là nameposts. Các field trên một kiểu object có thể tùy chọn hoặc bắt buộc. Ở ví dụ trên field name là bắt buộc vì có ký hiệu !.

Arguments

các field trong schema chấp nhận tham số. Các tham số này có thể tùy chọn hoặc bắt buộc (xác định bởi ký hiệu !).

 type Post {
      allowComments(comments: Boolean!)
    }

Scalar Types

GraphQL có những scalar type là:

  • Int
  • Float
  • String
  • Boolean
  • ID

Các field có kiểu scalar thì không thể chứa các field khác. Ta cũng có thể chỉ định kiểu scalar custom sử dụng từ khóa scalar. Ví dụ ta có thể định nghĩa kiểu Date:

scalar Date

Enumeration types

Kiểu enumeration là một kiểu đặc biệt của scalar, giới hạn trong một tập các giá trị cho phép. Nó cho phép validate các tham số của kiểu này phải là một trong các giá trị trong tập cho phép, quy định giá trị của một field sẽ luôn là một trong các giá trị của một tập hữu hạn.

Một định nghĩa enum trong GraphQL schema language có dạng:

 enum Media {
      Image
      Video
    }

Input types

Kiểu input được sử dụng trong trường hợp mutation, khi bạn muốn tạo một object. Trong GraphQL schema language, kiểu input giống hoàn toàn với các kiểu thông thường khác, ngoại trừ dùng từ khóa input thay vì type. Ví dụ:

input CommentInput {
      body: String!
    }

Những field của object kiểu input cũng có thể là những object kiểu input. Object kiểu input không thể chứa tham số trong các field của nó

Tham khảo

https://blog.pusher.com/getting-up-and-running-with-graphql/


All Rights Reserved