Tổng quan về việc triển khai Client GraphQL và các tính năng cốt lõi

GraphQL thường được vận hành thông qua giao thức HTTP, do đó khái niệm "client" ở đây đề cập đến các tác nhân khởi tạo yêu cầu HTTP nhằm giao tiếp với máy chủ GraphQL.

Về mặt giao tiếp, GraphQL sử dụng các truy vấn (query) để trao đổi dữ liệu. Về lý thuyết, cả phương thức GET và POST đều có thể sử dụng được. Tuy nhiên, GET yêu cầu truy vấn phải được mã hóa vào URL, dẫn đến việc xử lý chuỗi query và các ký tự đặc biệt trở nên phức tạp. Do đó, hầu hết các hệ thống đều ưu tiên sử dụng phương thức POST và đưa dữ liệu truy vấn vào phần thân (body) của yêu cầu.

# Ví dụ sử dụng cURL với phương thức POST
curl -X POST http://api.example.com/graphql \
  -H "Content-Type: application/json" \
  -d '{
    "query": "{ systemStatus }"
  }'
# Phản hồi từ máy chủ
{
  "data": {
    "systemStatus": "operational"
  }
}

Mặc dù hiếm khi được sử dụng, phương thức GET vẫn hoàn toàn khả thi nếu bạn xử lý đúng việc mã hóa URL:

# Ví dụ sử dụng cURL với phương thức GET
curl "http://api.example.com/graphql?query=%7B%20systemStatus%20%7D"

Thực thi yêu cầu từ Frontend

Để minh họa việc gửi mutation từ trình duyệt, ví dụ dưới đây sử dụng Fetch API để tạo một phòng ban mới:

const requestPayload = {
  query: `mutation CreateNewDept($input: DeptInput!) {
    addDepartment(dept: $input) {
      id
      name
      location
    }
  }`,
  variables: {
    input: {
      name: "Human Resources",
      location: "Ho Chi Minh City"
    }
  }
};

fetch('http://api.example.com/graphql', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Accept': 'application/json',
  },
  body: JSON.stringify(requestPayload)
})
  .then(res => res.json())
  .then(data => console.log(data));
# Kết quả trả về
{
  "data": {
    "addDepartment": {
      "id": "d-123456",
      "name": "Human Resources",
      "location": "Ho Chi Minh City"
    }
  }
}

Tên thao tác (Operation Name)

>Những ví dụ trước sử dụng cú pháp viết tắt, bỏ qua từ khóa query và tên của truy vấn. Tuy nhiên, trong môi trường sản xuất (production), việc đặt tên cho thao tác là rất quan trọng để giúp việc gỡ lỗi và theo dõi log trở nên rõ ràng hơn, giảm thiểu sự mơ hồ trong mã nguồn.

query GetAllDepartments {
  departments {
    id
    name
    location
  }
}

Định danh (Aliases)

>Khi bạn cần yêu cầu cùng một trường (field) nhưng với các tham số khác nhau trong một truy vấn, tên trường sẽ bị xung đột. GraphQL sử dụng định danh (aliases) để phân biệt kết quả trả về.

query {
  hq: getDepartment(id: "10") {
    name
  }
  branch: getDepartment(id: "20") {
    name
  }
}
# Kết quả phản hồi
{
  "data": {
    "hq": {
      "name": "Headquarters"
    },
    "branch": {
      "name": "South Branch"
    }
  }
}

Phân mảnh (Fragments)

>Phân mảnh (Fragments) là các đơn vị tái sử dụng được, cho phép bạn định nghĩa một tập hợp các trường và sử dụng lại chúng ở nhiều nơi trong truy vấn.

query {
  hq: getDepartment(id: "10") {
    ...deptInfo
  }
  branch: getDepartment(id: "20") {
    ...deptInfo
  }
}

fragment deptInfo on Department {
  name
  location
}

Chỉ thị (Directives)

>GraphQL hỗ trợ việc xây dựng truy vấn động thông qua các biến và chỉ thị (directives). Specifications cốt lõi của GraphQL định nghĩa hai chỉ thị bắt buộc phải được hỗ trợ:

  • @include(if: Boolean): Chỉ bao gồm trường này nếu tham số là true.
  • @skip(if: Boolean): Bỏ qua trường này nếu tham số là true.
query GetDepartmentList($withLocation: Boolean!) {
  departments {
    name
    location @include(if: $withLocation)
  }
}
# Biến đầu vào (Variables)
{
  "withLocation": false
}
# Kết quả khi withLocation là false
{
  "data": {
    "departments": [
      { "name": "IT" },
      { "name": "Sales" },
      { "name": "Marketing" }
    ]
  }
}

Giá trị biến mặc định

>Bạn có thể thiết lập giá trị mặc định cho các biến ngay trong định nghĩa truy vấn. Nếu không cung cấp giá trị từ phía client, giá trị mặc định này sẽ được sử dụng.

query GetDepartmentList($withLocation: Boolean = true) {
  departments {
    name
    location @include(if: $withLocation)
  }
}
# Biến đầu vào rỗng
{}
# Kết quả sẽ sử dụng giá trị mặc định true
{
  "data": {
    "departments": [
      { "name": "IT", "location": "Floor 1" },
      { "name": "Sales", "location": "Floor 2" }
    ]
  }
}

Thẻ: graphql HTTP Client Fetch API Web Development Query Language

Đăng vào ngày 18 tháng 9 lúc 00:17