Mẹo tăng hiệu suất

Tài liệu này bao gồm một số kỹ thuật bạn có thể sử dụng để cải thiện hiệu suất của ứng dụng. Trong một số trường hợp, các ví dụ từ các API khác hoặc API chung được dùng để minh hoạ các ý tưởng trình bày. Tuy nhiên, các khái niệm tương tự cũng áp dụng cho API Sách.

Nén bằng gzip

Một cách dễ dàng và thuận tiện để giảm băng thông cần thiết cho mỗi yêu cầu là bật tính năng nén gzip. Mặc dù điều này yêu cầu thêm thời gian của CPU để giải nén kết quả, nhưng sự đánh đổi với chi phí mạng thường làm cho rất đáng giá.

Để nhận phản hồi được mã hoá gzip, bạn phải thực hiện hai việc: Đặt tiêu đề Accept-Encoding và sửa đổi tác nhân người dùng để chứa chuỗi gzip. Dưới đây là ví dụ về tiêu đề HTTP được định dạng đúng để bật tính năng nén gzip:

Accept-Encoding: gzip
User-Agent: my program (gzip)

Làm việc với một phần tài nguyên

Một cách khác để cải thiện hiệu suất cho lệnh gọi API là chỉ gửi và nhận phần dữ liệu mà bạn quan tâm. Điều này cho phép ứng dụng của bạn tránh được việc truyền, phân tích cú pháp và lưu trữ các trường không cần thiết, nhờ đó ứng dụng có thể sử dụng tài nguyên như mạng, CPU và bộ nhớ một cách hiệu quả hơn.

Có hai loại yêu cầu một phần:

  • Phản hồi một phần: Yêu cầu mà bạn chỉ định các trường cần đưa vào phản hồi (sử dụng tham số yêu cầu fields).
  • Patch: Yêu cầu cập nhật trong đó bạn chỉ gửi các trường mà bạn muốn thay đổi (sử dụng động từ HTTP PATCH).

Bạn có thể xem thêm thông tin chi tiết về việc tạo một phần yêu cầu trong các phần sau.

Phản hồi một phần

Theo mặc định, máy chủ sẽ gửi lại bản trình bày đầy đủ của một tài nguyên sau khi xử lý các yêu cầu. Để cải thiện hiệu suất, bạn có thể yêu cầu máy chủ chỉ gửi những trường mà bạn thực sự cần và nhận một phần phản hồi.

Để yêu cầu phản hồi một phần, hãy sử dụng tham số yêu cầu fields để chỉ định các trường bạn muốn trả về. Bạn có thể sử dụng tham số này với bất kỳ yêu cầu nào trả về dữ liệu phản hồi.

Xin lưu ý rằng thông số fields chỉ ảnh hưởng đến dữ liệu phản hồi; không ảnh hưởng đến dữ liệu mà bạn cần gửi (nếu có). Để giảm lượng dữ liệu mà bạn gửi khi sửa đổi tài nguyên, hãy sử dụng yêu cầu bản vá.

Ví dụ:

Ví dụ sau đây cho thấy việc sử dụng tham số fields với API "Bản minh hoạ" chung (hư cấu).

Yêu cầu đơn giản: Yêu cầu HTTP GET này bỏ qua tham số fields và trả về toàn bộ tài nguyên.

https://www.googleapis.com/demo/v1

Phản hồi đầy đủ tài nguyên: Dữ liệu đầy đủ về tài nguyên bao gồm các trường sau đây cùng với nhiều trường khác đã bị bỏ qua để ngắn gọn.

{
  "kind": "demo",
  ...
  "items": [
  {
    "title": "First title",
    "comment": "First comment.",
    "characteristics": {
      "length": "short",
      "accuracy": "high",
      "followers": ["Jo", "Will"],
    },
    "status": "active",
    ...
  },
  {
    "title": "Second title",
    "comment": "Second comment.",
    "characteristics": {
      "length": "long",
      "accuracy": "medium"
      "followers": [ ],
    },
    "status": "pending",
    ...
  },
  ...
  ]
}

Yêu cầu cho phản hồi một phần: Yêu cầu sau đây cho cùng một tài nguyên này sử dụng tham số fields để giảm đáng kể lượng dữ liệu được trả về.

https://www.googleapis.com/demo/v1?fields=kind,items(title,characteristics/length)

Phản hồi một phần: Để phản hồi yêu cầu ở trên, máy chủ sẽ gửi lại phản hồi chỉ chứa thông tin loại cùng với một mảng mục được phân tích cú pháp chỉ bao gồm thông tin đặc trưng về độ dài và tiêu đề HTML trong mỗi mục.

200 OK
{
  "kind": "demo",
  "items": [{
    "title": "First title",
    "characteristics": {
      "length": "short"
    }
  }, {
    "title": "Second title",
    "characteristics": {
      "length": "long"
    }
  },
  ...
  ]
}

Lưu ý rằng phản hồi là một đối tượng JSON chỉ bao gồm các trường đã chọn và các đối tượng mẹ trong đó.

Tiếp theo là thông tin chi tiết về cách định dạng thông số fields, tiếp theo là thông tin chi tiết hơn về nội dung được trả về chính xác trong phản hồi.

Tóm tắt cú pháp thông số trường

Định dạng của giá trị tham số yêu cầu fields là thoải mái dựa trên cú pháp CUE. Cú pháp được hỗ trợ được tóm tắt bên dưới và ví dụ bổ sung được cung cấp trong phần sau.

  • Sử dụng danh sách được phân tách bằng dấu phẩy để chọn nhiều trường.
  • Sử dụng a/b để chọn trường b lồng trong trường a; sử dụng a/b/c để chọn trường c lồng trong b.

    Ngoại lệ: Đối với các phản hồi API sử dụng trình bao bọc "dữ liệu", trong đó phản hồi được lồng vào một đối tượng data trông giống như data: { ... }, không bao gồm "data" trong thông số kỹ thuật fields. Việc bao gồm đối tượng dữ liệu có thông số kỹ thuật cho các trường như data/a/b sẽ gây ra lỗi. Thay vào đó, bạn chỉ cần sử dụng quy cách fields như a/b.

  • Sử dụng một bộ chọn phụ để yêu cầu một tập hợp các trường phụ hoặc mảng cụ thể bằng cách đặt các biểu thức trong dấu ngoặc đơn "( )".

    Ví dụ: fields=items(id,author/email) chỉ trả về mã mặt hàng và email của tác giả cho từng phần tử trong mảng mặt hàng. Bạn cũng có thể chỉ định một trường phụ, trong đó fields=items(id) tương đương với fields=items/id.

  • Sử dụng ký tự đại diện trong các lựa chọn trường, nếu cần.

    Ví dụ: fields=items/pagemap/* chọn tất cả đối tượng trong sơ đồ trang.

Ví dụ khác về cách sử dụng thông số trường

Các ví dụ bên dưới bao gồm mô tả về cách giá trị tham số fields ảnh hưởng đến phản hồi.

Lưu ý: Giống như với tất cả các giá trị tham số truy vấn, giá trị tham số fields phải được mã hóa URL. Để dễ đọc hơn, các ví dụ trong tài liệu này sẽ bỏ qua việc mã hoá.

Xác định các trường bạn muốn trả về hoặc chọn trường.
Giá trị tham số yêu cầu fields là danh sách các trường được phân tách bằng dấu phẩy và mỗi trường được chỉ định tương ứng với thư mục gốc của phản hồi. Do đó, nếu bạn đang thực hiện thao tác danh sách, thì phản hồi sẽ là một tập hợp và thường bao gồm một loạt tài nguyên. Nếu bạn đang thực hiện một thao tác trả về một tài nguyên, các trường được chỉ định tương ứng với tài nguyên đó. Nếu trường bạn chọn là (hoặc là một phần của) một mảng, máy chủ sẽ trả về phần đã chọn của tất cả các phần tử trong mảng.

Dưới đây là một số ví dụ ở cấp bộ sưu tập:
Ví dụ Hiệu quả
items Trả về tất cả phần tử trong mảng items (bao gồm tất cả các trường trong mỗi phần tử) nhưng không trả về trường nào khác.
etag,items Trả về cả trường etag và tất cả phần tử trong mảng items.
items/title Chỉ trả về trường title cho tất cả các phần tử trong mảng items.

Bất cứ khi nào một trường lồng nhau được trả về, phản hồi sẽ bao gồm các đối tượng mẹ trong đó. Các trường mẹ không bao gồm bất kỳ trường con nào khác trừ khi các trường đó cũng được chọn rõ ràng.
context/facets/label Chỉ trả về trường label cho tất cả các thành phần của mảng facets. Lớp này tự lồng nhau trong đối tượng context.
items/pagemap/*/title Đối với mỗi phần tử trong mảng items, chỉ trả về trường title (nếu có) của tất cả các đối tượng con của pagemap.

Dưới đây là một số ví dụ ở cấp tài nguyên:
Ví dụ Hiệu quả
title Trả về trường title của tài nguyên được yêu cầu.
author/uri Trả về trường phụ uri của đối tượng author trong tài nguyên được yêu cầu.
links/*/href
Trả về trường href của tất cả các đối tượng là phần tử con của links.
Chỉ yêu cầu một số phần của trường cụ thể bằng cách sử dụng tính năng chọn phụ.
Theo mặc định, nếu yêu cầu của bạn chỉ định các trường cụ thể, thì máy chủ sẽ trả về toàn bộ các đối tượng hoặc phần tử mảng. Bạn có thể chỉ định một phản hồi chỉ bao gồm một số trường phụ. Bạn thực hiện việc này bằng cách sử dụng cú pháp lựa chọn phụ "( )", như trong ví dụ bên dưới.
Ví dụ: Hiệu quả
items(title,author/uri) Chỉ trả về các giá trị của titleuri của tác giả cho từng phần tử trong mảng items.

Xử lý các phản hồi một phần

Sau khi xử lý một yêu cầu hợp lệ chứa tham số truy vấn fields, máy chủ sẽ gửi lại mã trạng thái HTTP 200 OK cùng với dữ liệu được yêu cầu. Nếu tham số truy vấn fields có lỗi hoặc không hợp lệ, máy chủ sẽ trả về mã trạng thái HTTP 400 Bad Request, cùng với thông báo lỗi cho người dùng biết về sự cố đã chọn trong các trường (ví dụ: "Invalid field selection a/b").

Dưới đây là ví dụ về một phần phản hồi hiển thị trong phần giới thiệu ở trên. Yêu cầu này sử dụng tham số fields để chỉ định trường nào cần trả về.

https://www.googleapis.com/demo/v1?fields=kind,items(title,characteristics/length)

Câu trả lời một phần sẽ có dạng như sau:

200 OK
{
  "kind": "demo",
  "items": [{
    "title": "First title",
    "characteristics": {
      "length": "short"
    }
  }, {
    "title": "Second title",
    "characteristics": {
      "length": "long"
    }
  },
  ...
  ]
}

Lưu ý: Đối với các API hỗ trợ các tham số truy vấn để phân trang dữ liệu (ví dụ: maxResultsnextPageToken), hãy sử dụng các tham số đó để giảm kết quả của mỗi truy vấn thành kích thước có thể quản lý. Nếu không, hiệu suất có thể đạt được nếu phản hồi một phần có thể không nhận ra.

Bản vá (cập nhật một phần)

Bạn cũng có thể tránh gửi dữ liệu không cần thiết khi sửa đổi tài nguyên. Để chỉ gửi dữ liệu cập nhật cho các trường cụ thể mà bạn đang thay đổi, hãy sử dụng động từ HTTP PATCH. Ngữ nghĩa của bản vá được mô tả trong tài liệu này khác (và đơn giản hơn) với các cách triển khai GData cũ, cập nhật một phần.

Ví dụ ngắn bên dưới cho thấy cách sử dụng bản vá sẽ giảm thiểu dữ liệu bạn cần gửi để thực hiện cập nhật nhỏ.

Ví dụ:

Ví dụ này cho thấy một yêu cầu bản vá đơn giản chỉ cập nhật tiêu đề của một tài nguyên API "Bản minh hoạ" chung (hư cấu). Tài nguyên này cũng có một nhận xét, một tập hợp các đặc điểm, trạng thái và nhiều trường khác, nhưng yêu cầu này chỉ gửi trường title vì đó là trường duy nhất đang được sửa đổi:

PATCH https://www.googleapis.com/demo/v1/324
Authorization: Bearer your_auth_token
Content-Type: application/json

{
  "title": "New title"
}

Phản hồi:

200 OK
{
  "title": "New title",
  "comment": "First comment.",
  "characteristics": {
    "length": "short",
    "accuracy": "high",
    "followers": ["Jo", "Will"],
  },
  "status": "active",
  ...
}

Máy chủ trả về mã trạng thái 200 OK, cùng với nội dung biểu diễn đầy đủ của tài nguyên được cập nhật. Vì chỉ có trường title được bao gồm trong yêu cầu bản vá, nên đó là giá trị duy nhất khác với trước đây.

Lưu ý: Nếu sử dụng thông số Một phần phản hồi fields cùng với bản vá, thì bạn có thể tăng hiệu quả của các yêu cầu cập nhật hơn nữa. Yêu cầu bản vá chỉ làm giảm kích thước của yêu cầu. Phản hồi một phần làm giảm kích thước của phản hồi. Vì vậy, để giảm lượng dữ liệu được gửi ở cả hai hướng, hãy sử dụng yêu cầu bản vá với thông số fields.

Ngữ nghĩa của một yêu cầu bản vá

Phần nội dung của yêu cầu bản vá chỉ bao gồm các trường tài nguyên mà bạn muốn sửa đổi. Khi chỉ định một trường, bạn phải bao gồm mọi đối tượng mẹ đính kèm, giống như trường hợp cha mẹ đính kèm được trả về kèm theo phản hồi một phần. Dữ liệu đã sửa đổi mà bạn gửi sẽ được hợp nhất vào dữ liệu của đối tượng mẹ (nếu có).

  • Thêm: Để thêm một trường chưa tồn tại, hãy chỉ định trường mới và giá trị của trường đó.
  • Sửa đổi: Để thay đổi giá trị của trường hiện có, hãy chỉ định trường và đặt trường đó thành giá trị mới.
  • Xoá: Để xoá một trường, hãy chỉ định trường đó và đặt trường đó thành null. Ví dụ: "comment": null. Bạn cũng có thể xoá toàn bộ đối tượng (nếu có thể thay đổi) bằng cách đặt đối tượng đó thành null. Nếu bạn đang sử dụng Thư viện ứng dụng API Java, hãy sử dụng Data.NULL_STRING. Để biết thông tin chi tiết, hãy xem null rỗng.

Lưu ý về mảng: Yêu cầu vá có chứa mảng thay thế mảng hiện tại bằng mảng mà bạn cung cấp. Bạn không thể sửa đổi, thêm hoặc xóa các mục theo mảng.

Sử dụng bản vá trong chu trình đọc-sửa-ghi

Bạn có thể bắt đầu bằng cách truy xuất một phần phản hồi với dữ liệu bạn muốn sửa đổi. Điều này đặc biệt quan trọng đối với các tài nguyên sử dụng ETag vì bạn phải cung cấp giá trị ETag hiện tại trong tiêu đề HTTP If-Match để cập nhật tài nguyên thành công. Sau khi nhận được dữ liệu, bạn có thể sửa đổi các giá trị mà bạn muốn thay đổi và gửi lại nội dung biểu diễn một phần đã được sửa đổi bằng yêu cầu bản vá. Sau đây là ví dụ giả định tài nguyên minh hoạ sử dụng ETag:

GET https://www.googleapis.com/demo/v1/324?fields=etag,title,comment,characteristics
Authorization: Bearer your_auth_token

Đây là phản hồi một phần:

200 OK
{
  "etag": "ETagString"
  "title": "New title"
  "comment": "First comment.",
  "characteristics": {
    "length": "short",
    "level": "5",
    "followers": ["Jo", "Will"],
  }
}

Yêu cầu bản vá sau đây dựa trên phản hồi đó. Như hình dưới đây, ứng dụng cũng sử dụng thông số fields để giới hạn dữ liệu trả về trong phản hồi của bản vá:

PATCH https://www.googleapis.com/demo/v1/324?fields=etag,title,comment,characteristics
Authorization: Bearer your_auth_token
Content-Type: application/json
If-Match: "ETagString"
{
  "etag": "ETagString"
  "title": "",                  /* Clear the value of the title by setting it to the empty string. */
  "comment": null,              /* Delete the comment by replacing its value with null. */
  "characteristics": {
    "length": "short",
    "level": "10",              /* Modify the level value. */
    "followers": ["Jo", "Liz"], /* Replace the followers array to delete Will and add Liz. */
    "accuracy": "high"          /* Add a new characteristic. */
  },
}

Máy chủ phản hồi bằng mã trạng thái HTTP 200 OK và bản trình bày một phần của tài nguyên được cập nhật:

200 OK
{
  "etag": "newETagString"
  "title": "",                 /* Title is cleared; deleted comment field is missing. */
  "characteristics": {
    "length": "short",
    "level": "10",             /* Value is updated.*/
    "followers": ["Jo" "Liz"], /* New follower Liz is present; deleted Will is missing. */
    "accuracy": "high"         /* New characteristic is present. */
  }
}

Trực tiếp tạo yêu cầu bản vá

Đối với một số yêu cầu bản vá, bạn cần căn cứ vào dữ liệu mà bạn đã truy xuất trước đó. Ví dụ: nếu bạn muốn thêm một mục vào một mảng và không muốn mất bất kỳ phần tử mảng nào hiện có, bạn phải nhận dữ liệu hiện có trước. Tương tự như vậy, nếu API sử dụng ETag, bạn cần gửi giá trị ETag trước đó cùng với yêu cầu của mình để cập nhật tài nguyên thành công.

Lưu ý: Bạn có thể dùng tiêu đề HTTP "If-Match: *" để buộc sử dụng một bản vá khi đang sử dụng ETag. Nếu làm như vậy, bạn không cần phải đọc trước khi ghi.

Tuy nhiên, trong các trường hợp khác, bạn có thể tạo yêu cầu bản vá trực tiếp mà không cần truy xuất dữ liệu hiện có trước. Ví dụ: bạn có thể dễ dàng thiết lập yêu cầu bản vá cập nhật một trường thành giá trị mới hoặc thêm trường mới. Dưới đây là ví dụ:

PATCH https://www.googleapis.com/demo/v1/324?fields=comment,characteristics
Authorization: Bearer your_auth_token
Content-Type: application/json

{
  "comment": "A new comment",
  "characteristics": {
    "volume": "loud",
    "accuracy": null
  }
}

Với yêu cầu này, nếu trường nhận xét có giá trị hiện có thì giá trị mới sẽ ghi đè lên giá trị đó; nếu không thì trường đó sẽ được đặt thành giá trị mới. Tương tự, nếu có một đặc điểm khối lượng, thì giá trị của nó sẽ bị ghi đè; nếu không, giá trị đó sẽ được tạo. Trường độ chính xác, nếu được đặt, sẽ bị xoá.

Xử lý phản hồi cho bản vá

Sau khi xử lý yêu cầu bản vá hợp lệ, API sẽ trả về mã phản hồi HTTP 200 OK cùng với nội dung biểu diễn đầy đủ của tài nguyên được sửa đổi. Nếu API sử dụng ETag, máy chủ sẽ cập nhật các giá trị ETag khi xử lý thành công một yêu cầu bản vá, giống như với PUT.

Yêu cầu bản vá trả về toàn bộ bản trình bày tài nguyên trừ khi bạn sử dụng tham số fields để giảm lượng dữ liệu mà nó trả về.

Nếu yêu cầu bản vá dẫn đến trạng thái tài nguyên mới không hợp lệ về mặt cú pháp hoặc ngữ nghĩa, thì máy chủ sẽ trả về mã trạng thái HTTP 400 Bad Request hoặc 422 Unprocessable Entity và trạng thái tài nguyên không thay đổi. Ví dụ: Nếu bạn cố gắng xóa giá trị trong một trường bắt buộc, máy chủ sẽ trả về một lỗi.

Ký hiệu thay thế khi động từ patCH HTTP không được hỗ trợ

Nếu tường lửa của bạn không cho phép gửi yêu cầu HTTP PATCH, hãy gửi yêu cầu HTTP POST và đặt tiêu đề ghi đè thành PATCH như sau:

POST https://www.googleapis.com/...
X-HTTP-Method-Override: PATCH
...

Sự khác biệt giữa bản vá và bản cập nhật

Trong thực tế, khi gửi dữ liệu cho một yêu cầu cập nhật sử dụng động từ HTTP PUT, bạn chỉ cần gửi những trường bắt buộc hoặc không bắt buộc; nếu bạn gửi giá trị cho các trường do máy chủ đặt thì chúng sẽ bị bỏ qua. Mặc dù đây có vẻ là một cách khác để cập nhật một phần, nhưng phương pháp này có một số hạn chế. Với các bản cập nhật sử dụng động từ HTTP PUT, yêu cầu sẽ không thành công nếu bạn không cung cấp các tham số bắt buộc và sẽ xoá dữ liệu đã đặt trước đó nếu bạn không cung cấp các tham số tuỳ chọn.

Vì thế, sử dụng bản vá sẽ an toàn hơn nhiều. Bạn chỉ cung cấp dữ liệu cho các trường mà bạn muốn thay đổi; các trường mà bạn bỏ qua sẽ không bị xóa. Ngoại lệ duy nhất của quy tắc này xảy ra với các phần tử hoặc mảng lặp lại: Nếu bạn bỏ qua tất cả các phần tử hoặc mảng, thì toàn bộ tập hợp hoặc phần tử đó sẽ được thay thế bằng tập hợp bạn cung cấp.