Tài liệu này bao gồm một số kỹ thuật mà 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, ví dụ từ các API khác hoặc cá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ó thể áp dụng cho các API Blogger.
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 đòi hỏi 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 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 hợp lệ để 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 của các 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 chuyển, phân tích cú pháp và lưu trữ các trường không cần thiết, để ứng dụng có thể sử dụng tài nguyên bao gồm mạng, CPU và bộ nhớ 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: Một yêu cầu mà bạn chỉ định những 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ề cách thực hiện yêu cầu một phần 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ý 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 phản hồi một phần.
Để yêu cầu phản hồi một phần, hãy dùng tham số yêu cầu fields
để chỉ định các trường mà bạn muốn trả về. Bạn có thể 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 tham số fields
chỉ ảnh hưởng đến dữ liệu phản hồi chứ 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 dùng yêu cầu bản vá.
Ví dụ:
Ví dụ sau cho thấy việc sử dụng tham số fields
với API chung (hư cấu) "demo".
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 tài nguyên đầy đủ bao gồm các trường sau, cùng với nhiều trường khác đã bị bỏ qua cho 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 phản hồi một phần: Yêu cầu sau cho cùng một tài nguyên này sử dụng thông 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ủ gửi lại một phản hồi chỉ chứa thông tin loại cùng với một mảng mục được rút gọn chỉ bao gồm thông tin đặc điểm tiêu đề và độ dài HTML trong mỗi mục.
200 OK
{ "kind": "demo", "items": [{ "title": "First title", "characteristics": { "length": "short" } }, { "title": "Second title", "characteristics": { "length": "long" } }, ... ] }
Xin 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ẹ xung quanh.
Tiếp theo, chúng tôi sẽ trình bày chi tiết về cách định dạng thông số fields
, sau đó là thông tin chi tiết hơn về chính xác nội dung được trả về trong phản hồi.
Tóm tắt cú pháp thông số các trường
Định dạng của giá trị tham số yêu cầu fields
được dựa trên cú pháp XPath được thả lỏng. Cú pháp được hỗ trợ được tóm tắt như dưới đây và các ví dụ khác đượ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ườngb
lồng trong trườnga
; sử dụnga/b/c
để chọn trườngc
lồng trongb
.
Ngoại lệ: Đối với các phản hồi API sử dụng "data" trình bao bọc, trong đó phản hồi được lồng trong một đối tượng
data
trông giốngdata: { ... }
, không bao gồm "data
" trong thông số kỹ thuậtfields
. Việc cung cấp đối tượng dữ liệu có thông số trường nhưdata/a/b
sẽ gây ra lỗi. Thay vào đó, bạn chỉ cần sử dụng một thông số kỹ thuật củafields
nhưa/b
. - Hãy sử dụng bộ chọn phụ để yêu cầu một tập hợp các trường con cụ thể của mảng hoặc đối tượng bằng cách đặt 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 thành phần trong mảng mặt hàng. Bạn cũng có thể chỉ định một trường con, trong đófields=items(id)
tương đương vớifields=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.
Các ví dụ khác về việc sử dụng thông số trường
Các ví dụ bên dưới bao gồm thông tin mô tả về tác động của giá trị thông số fields
đối với phản hồi.
Lưu ý: Giống như tất 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 bỏ qua phần mã hoá.
- Xác định các trường bạn muốn trả về hoặc chọn trường được chọn.
- 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 một thao tác danh sách, thì phản hồi là một tập hợp và thường bao gồm một mảng 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 duy nhất, thì các trường sẽ đượ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 được chọn của tất cả các thành phần 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ả các thành phần trong mảng items, bao gồm tất cả các trường trong mỗi thành phần, nhưng không trả về trường nào khác. etag,items
Trả về cả trường etag
và mọi thành phần 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.
Mỗi khi một trường lồng nhau được trả về, phản hồi sẽ bao gồm các đối tượng mẹ xung quanh. Các trường chính không bao gồm các trường con khác trừ khi được chọn rõ ràng.context/facets/label
Chỉ trả về trường label
cho tất cả thành viên của mảngfacets
. Thuộc tính này được lồng trong đối tượngcontext
.items/pagemap/*/title
Đối với mỗi phần tử trong mảng mặt hàng, chỉ trả về trường title
(nếu có) của tất cả các đối tượng là phần tử con củapagemap
.
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ượngauthor
trong tài nguyên được yêu cầu.links/*/href
Trả về trường href
của tất cả đối tượng là phần tử con củalinks
. - Chỉ yêu cầu các phần của một số trường cụ thể bằng cách sử dụng lựa 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ộ đối tượng hoặc phần tử mảng. Bạn có thể chỉ định một câu trả lời chỉ bao gồm một số trường con. 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 title
vàuri
của tác giả cho từng phần tử trong mảng items.
Xử lý một phần phản hồi
Sau khi xử lý một yêu cầu hợp lệ bao gồm 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 điều gì đang xảy ra với lựa chọn trường của họ (ví dụ: "Invalid field selection a/b"
).
Đây là ví dụ về phản hồi một phần trong phần giới thiệu ở trên. Yêu cầu này sử dụng thông số fields
để chỉ định trường cần trả về.
https://www.googleapis.com/demo/v1?fields=kind,items(title,characteristics/length)
Phản hồi một phần 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ụ: maxResults
và nextPageToken
), hãy sử dụng các tham số đó để giảm kết quả của mỗi truy vấn xuống kích thước có thể quản lý được. 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 được ghi nhận.
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 dùng động từ HTTP PATCH
. Ngữ nghĩa của bản vá được mô tả trong tài liệu này sẽ khác (và đơn giản hơn) so với cách triển khai GData cũ, cập nhật một phần của bản cập nhật một phần.
Ví dụ ngắn dưới đây cho thấy việc sử dụng bản vá sẽ giảm thiểu dữ liệu bạn cần gửi để tạo một bản cập nhật nhỏ.
Ví dụ:
Ví dụ này cho thấy một yêu cầu đơn giản để cập nhật bản vá chỉ nhằm cập nhật tiêu đề của một tài nguyên API (giả tưởng) "Demo" chung. Tài nguyên này cũng có một nhận xét, một nhóm đặ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 bản trình bày đầy đủ về tài nguyên đã 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 đó.
Lưu ý: Nếu kết hợp thông số một phần phản hồi fields
với bản vá, bạn có thể nâng cao hiệu quả của các yêu cầu cập nhật. 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 chiều, hãy sử dụng yêu cầu bản vá có 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ư khi đối tượng mẹ được bao quanh trả về kèm theo một 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 giá trị mới cho trường đó.
- Xoá: Để xoá một trường, hãy chỉ định trường đó và đặt 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ànhnull
. Nếu bạn đang sử dụng Thư viện ứng dụng Java API, hãy sử dụngData.NULL_STRING
. Để biết thông tin chi tiết, hãy xem JSON null.
Lưu ý về mảng: Yêu cầu bản vá chứa mảng thay thế mảng hiện có bằng mảng bạn cung cấp. Bạn không thể sửa đổi, thêm hoặc xoá các mục trong một mảng theo kiểu từng phần.
Sử dụng bản vá trong chu kỳ đọc-sửa đổi-ghi
Bạn nên bắt đầu bằng cách truy xuất phản hồi một phần bằng 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ình muốn thay đổi và gửi lại phần trình bày sửa đổi một phần bằng yêu cầu bản vá. Dưới đâ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ư minh hoạ bên dưới, nó cũng sử dụng thông số fields
để giới hạn dữ liệu được 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à biểu diễn 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. */ } }
Tạo yêu cầu bản vá trực tiếp
Đối với một số yêu cầu vá lỗi, bạn cần căn cứ vào dữ liệu 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ỳ thành phần mảng hiện có nào, thì trước tiên bạn phải lấy dữ liệu hiện có. Tương tự, nếu một API sử dụng ETag, thì bạn cần gửi giá trị ETag trước đó theo yêu cầu của bạn để cập nhật tài nguyên thành công.
Lưu ý: Bạn có thể sử dụng tiêu đề HTTP "If-Match: *"
để buộc thực hiện bản vá khi sử dụng ETag. Nếu làm như vậy, bạn không cần đọc lại 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 một 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 hiện có một giá trị, thì giá trị mới sẽ ghi đè lên giá trị đó; nếu không, giá trị mới 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, nó sẽ được tạo. Nếu bạn đặt trường này, độ chính xác sẽ bị xóa.
Xử lý phản hồi cho bản vá
Sau khi xử lý một yêu cầu bản vá hợp lệ, API sẽ trả về một mã phản hồi HTTP 200 OK
cùng với bản trình bày đầy đủ của tài nguyên đã sửa đổi. Nếu API sử dụng ETag, thì máy chủ sẽ cập nhật giá trị ETag khi xử lý thành công 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ộ cách trình bày tài nguyên trừ khi bạn sử dụng thông số fields
để giảm lượng dữ liệu mà nó trả về.
Nếu một 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 ngữ nghĩa 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 vẫn không thay đổi. Ví dụ: nếu bạn cố gắng xóa giá trị cho một trường bắt buộc, máy chủ sẽ trả về 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 các 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ư thể hiện dưới đây:
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 yêu cầu cập nhật dùng động từ HTTP PUT
, bạn chỉ cần gửi các 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ủ thiết lập, thì chúng sẽ bị bỏ qua. Mặc dù cách này có vẻ giống 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 thông số bắt buộc và sẽ xóa dữ liệu được đặt trước đó nếu bạn không cung cấp các thông số không bắt buộc.
Việc sử dụng bản vá sẽ an toàn hơn nhiều vì lý do này. Bạn chỉ cung cấp dữ liệu cho những trường mà bạn muốn thay đổi, còn những trường mà bạn bỏ qua sẽ không bị xóa. Ngoại lệ duy nhất đối với 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, chúng sẽ giữ nguyên như cũ; nếu bạn cung cấp bất kỳ phần tử hoặc mảng nào, thì toàn bộ tập hợp sẽ được thay thế bằng tập hợp mà bạn cung cấp.