Blogger JSON API: Tips Performa

Dokumen ini mencakup beberapa teknik yang dapat Anda gunakan untuk meningkatkan performa aplikasi Anda. Dalam beberapa kasus, contoh dari API lain atau API generik digunakan untuk mengilustrasikan ide yang disajikan. Namun, konsep yang sama berlaku untuk Blogger API.

Kompresi menggunakan gzip

Cara mudah dan nyaman untuk mengurangi bandwidth yang diperlukan untuk setiap permintaan adalah dengan mengaktifkan kompresi gzip. Meskipun hal ini memerlukan waktu CPU tambahan untuk membuka hasil, kompromi dengan biaya jaringan biasanya membuatnya sangat bermanfaat.

Untuk menerima respons yang dienkode dengan gzip, Anda harus melakukan dua hal: menetapkan header Accept-Encoding, dan mengubah agen pengguna agar berisi string gzip. Berikut contoh header HTTP yang diformat dengan benar untuk mengaktifkan kompresi gzip:

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

Bekerja dengan resource parsial

Cara lain untuk meningkatkan performa panggilan API Anda adalah dengan mengirim dan menerima hanya bagian data yang Anda minati. Hal ini memungkinkan aplikasi Anda menghindari transfer, penguraian, dan penyimpanan kolom yang tidak diperlukan sehingga dapat menggunakan resource termasuk jaringan, CPU, dan memori secara lebih efisien.

Ada dua jenis permintaan parsial:

  • Respons parsial: Permintaan yang menentukan kolom mana yang akan disertakan dalam respons (gunakan parameter permintaan fields).
  • Patch: Permintaan pembaruan tempat Anda hanya mengirim kolom yang ingin diubah (gunakan kata kerja HTTP PATCH).

Detail selengkapnya tentang cara membuat permintaan parsial dapat dilihat di bagian berikut.

Respons sebagian

Secara default, server mengirimkan kembali representasi lengkap resource setelah memproses permintaan. Untuk mendapatkan performa yang lebih baik, Anda dapat meminta server untuk hanya mengirimkan kolom yang benar-benar Anda butuhkan dan mendapatkan respons parsial.

Untuk meminta respons parsial, gunakan parameter permintaan fields untuk menentukan kolom yang ingin Anda tampilkan. Anda dapat menggunakan parameter ini dengan permintaan apa pun yang menampilkan data respons.

Perlu diketahui bahwa parameter fields hanya memengaruhi data respons; parameter ini tidak memengaruhi data yang perlu Anda kirim, jika ada. Untuk mengurangi jumlah data yang Anda kirim saat mengubah resource, gunakan permintaan patch.

Contoh

Contoh berikut menunjukkan penggunaan parameter fields dengan "Demo" API generik (fiktif).

Permintaan sederhana: Permintaan GET HTTP ini menghilangkan parameter fields dan menampilkan resource lengkap.

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

Respons resource penuh: Data resource lengkap mencakup kolom berikut, beserta banyak kolom lainnya yang telah dihilangkan agar lebih singkat.

{
  "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",
    ...
  },
  ...
  ]
}

Permintaan untuk respons parsial: Permintaan untuk resource yang sama berikut menggunakan parameter fields untuk mengurangi jumlah data yang ditampilkan secara signifikan.

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

Respons parsial: Sebagai respons terhadap permintaan di atas, server mengirimkan kembali respons yang hanya berisi informasi jenis beserta array item sederhana yang hanya menyertakan informasi judul dan karakteristik panjang HTML dalam setiap item.

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

Perhatikan bahwa respons adalah objek JSON yang hanya menyertakan kolom yang dipilih dan objek induknya yang mencakupnya.

Detail tentang cara memformat parameter fields akan dibahas berikutnya, diikuti dengan detail selengkapnya tentang apa yang sebenarnya ditampilkan dalam respons.

Ringkasan sintaksis parameter kolom

Format nilai parameter permintaan fields secara longgar berdasarkan sintaksis XPath. Sintaksis yang didukung dirangkum di bawah, dan contoh tambahan diberikan di bagian berikut.

  • Gunakan daftar yang dipisahkan koma untuk memilih beberapa kolom.
  • Gunakan a/b untuk memilih kolom b yang bertingkat di dalam kolom a; gunakan a/b/c untuk memilih kolom c yang disarangkan di dalam b.

    Pengecualian: Untuk respons API yang menggunakan wrapper data "data" dengan respons ditempatkan dalam objek data yang terlihat seperti data: { ... }, jangan sertakan "data" dalam spesifikasi fields. Menyertakan objek data dengan spesifikasi kolom seperti data/a/b menyebabkan error. Sebagai gantinya, cukup gunakan spesifikasi fields seperti a/b.

  • Gunakan sub-pemilih untuk meminta kumpulan sub-kolom tertentu dari array atau objek dengan menempatkan ekspresi dalam tanda kurung "( )".

    Misalnya: fields=items(id,author/email) hanya menampilkan ID item dan email penulis untuk setiap elemen dalam array item. Anda juga dapat menentukan satu sub-kolom, dengan fields=items(id) yang setara dengan fields=items/id.

  • Gunakan karakter pengganti dalam pilihan kolom, jika diperlukan.

    Misalnya: fields=items/pagemap/* memilih semua objek dalam peta halaman.

Contoh lain penggunaan parameter kolom

Contoh di bawah ini menjelaskan deskripsi tentang bagaimana nilai parameter fields memengaruhi respons.

Catatan: Seperti semua nilai parameter kueri, nilai parameter fields harus dienkode ke URL. Agar lebih mudah dibaca, contoh dalam dokumen ini menghilangkan encoding.

Identifikasi kolom yang ingin Anda kembalikan, atau buat pilihan kolom.
Nilai parameter permintaan fields adalah daftar kolom yang dipisahkan koma, dan setiap kolom ditentukan secara relatif terhadap root respons. Jadi, jika Anda menjalankan operasi daftar, responsnya adalah koleksi, dan umumnya mencakup array resource. Jika Anda melakukan operasi yang menampilkan satu resource, kolom ditentukan secara relatif terhadap resource tersebut. Jika kolom yang Anda pilih adalah (atau merupakan bagian dari) array, server akan menampilkan bagian yang dipilih dari semua elemen dalam array.

Berikut beberapa contoh tingkat koleksi:
Contoh Efek
items Menampilkan semua elemen dalam array item, termasuk semua kolom di setiap elemen, kecuali kolom lainnya.
etag,items Menampilkan kolom etag dan semua elemen dalam array item.
items/title Menampilkan kolom title saja untuk semua elemen dalam array item.

Setiap kali kolom bertingkat ditampilkan, respons akan menyertakan objek induk yang mencakupnya. Kolom induk tidak menyertakan kolom turunan lain, kecuali jika kolom tersebut juga dipilih secara eksplisit.
context/facets/label Hanya menampilkan kolom label untuk semua anggota array facets, yang bertingkat di bawah objek context.
items/pagemap/*/title Untuk setiap elemen dalam array item, hanya menampilkan kolom title (jika ada) untuk semua objek yang merupakan turunan dari pagemap.

Berikut beberapa contoh tingkat resource:
Contoh Efek
title Menampilkan kolom title dari resource yang diminta.
author/uri Menampilkan sub-kolom uri dari objek author di resource yang diminta.
links/*/href
Menampilkan kolom href dari semua objek yang merupakan turunan dari links.
Minta hanya bagian tertentu dari kolom tertentu menggunakan sub-pilihan.
Secara default, jika permintaan Anda menentukan kolom tertentu, server akan menampilkan objek atau elemen array secara keseluruhan. Anda dapat menentukan respons yang hanya menyertakan sub-kolom tertentu. Anda melakukannya menggunakan "( )" sintaksis sub-pilihan, seperti dalam contoh di bawah.
Contoh Efek
items(title,author/uri) Hanya menampilkan nilai title dan uri penulis untuk setiap elemen dalam array item.

Menangani respons parsial

Setelah memproses permintaan valid yang menyertakan parameter kueri fields, server akan mengirimkan kembali kode status HTTP 200 OK, beserta data yang diminta. Jika parameter kueri fields memiliki error atau tidak valid, server akan menampilkan kode status HTTP 400 Bad Request, beserta pesan error yang memberi tahu pengguna apa yang salah dengan pemilihan kolomnya (misalnya, "Invalid field selection a/b").

Berikut adalah contoh respons sebagian yang ditampilkan di bagian pengantar di atas. Permintaan menggunakan parameter fields untuk menentukan kolom mana yang akan ditampilkan.

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

Respons sebagian terlihat seperti ini:

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

Catatan: Untuk API yang mendukung parameter kueri untuk penomoran halaman data (misalnya, maxResults dan nextPageToken), gunakan parameter tersebut untuk mengurangi hasil setiap kueri ke ukuran yang dapat dikelola. Jika tidak, peningkatan performa yang mungkin terjadi dengan respons parsial mungkin tidak akan terwujud.

Patch (update sebagian)

Anda juga dapat menghindari pengiriman data yang tidak perlu saat mengubah resource. Untuk mengirim data yang diperbarui hanya untuk kolom tertentu yang Anda ubah, gunakan kata kerja PATCH HTTP. Semantik patch yang dijelaskan dalam dokumen ini berbeda (dan lebih sederhana) daripada penerapan GData yang lebih lama untuk update parsial.

Contoh singkat di bawah ini menunjukkan bagaimana penggunaan patch meminimalkan data yang perlu Anda kirim untuk membuat sedikit update.

Contoh

Contoh ini menunjukkan permintaan patch sederhana untuk hanya memperbarui judul resource API &fitual (fiktif) "Demo". Resource ini juga memiliki komentar, serangkaian karakteristik, status, dan banyak kolom lainnya, tetapi permintaan ini hanya mengirimkan kolom title, karena itu satu-satunya kolom yang diubah:

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

{
  "title": "New title"
}

Respons:

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

Server menampilkan kode status 200 OK, beserta representasi lengkap resource yang diperbarui. Karena hanya kolom title yang disertakan dalam permintaan patch, itu adalah satu-satunya nilai yang berbeda dari sebelumnya.

Catatan: Jika Anda menggunakan parameter fields respons sebagian yang dikombinasikan dengan patch, Anda dapat lebih meningkatkan efisiensi permintaan update Anda. Permintaan patch hanya mengurangi ukuran permintaan. Respons parsial mengurangi ukuran respons. Jadi, untuk mengurangi jumlah data yang dikirim ke kedua arah, gunakan permintaan patch dengan parameter fields.

Semantik permintaan patch

Isi permintaan patch hanya menyertakan kolom resource yang ingin diubah. Saat menentukan kolom, Anda harus menyertakan setiap objek induk yang mengapitnya, sama seperti induk yang menyertakannya ditampilkan dengan respons sebagian. Data yang diubah yang Anda kirim digabungkan ke dalam data untuk objek induk, jika ada.

  • Tambahkan: Untuk menambahkan kolom yang belum ada, tentukan kolom baru dan nilainya.
  • Mengubah: Untuk mengubah nilai kolom yang ada, tentukan kolom dan tetapkan ke nilai baru.
  • Hapus: Untuk menghapus kolom, tentukan kolom dan setel ke null. Misalnya, "comment": null. Anda juga dapat menghapus seluruh objek (jika dapat diubah) dengan menyetelnya ke null. Jika Anda menggunakan Library Klien Java API, gunakan Data.NULL_STRING; untuk mengetahui detailnya, lihat JSON null.

Catatan tentang array: Permintaan patch yang berisi array menggantikan array yang ada dengan yang Anda berikan. Anda tidak dapat memodifikasi, menambahkan, atau menghapus item dalam array dengan cara sedikit demi sedikit.

Menggunakan patch dalam siklus baca-ubah-tulis

Sebaiknya mulai dengan mengambil respons parsial dengan data yang ingin Anda ubah. Hal ini sangat penting untuk resource yang menggunakan ETag, karena Anda harus memberikan nilai ETag saat ini dalam header HTTP If-Match agar berhasil memperbarui resource. Setelah mendapatkan data, Anda kemudian dapat mengubah nilai yang ingin diubah dan mengirim kembali representasi parsial yang dimodifikasi dengan permintaan patch. Berikut adalah contoh yang mengasumsikan resource Demo menggunakan ETag:

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

Ini adalah respons sebagian:

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

Permintaan patch berikut didasarkan pada respons tersebut. Seperti yang ditunjukkan di bawah ini, kode ini juga menggunakan parameter fields untuk membatasi data yang ditampilkan dalam respons patch:

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. */
  },
}

Server merespons dengan kode status HTTP 200 OK, dan representasi parsial dari resource yang diperbarui:

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. */
  }
}

Membuat permintaan patch secara langsung

Untuk beberapa permintaan patch, Anda harus mendasarkannya pada data yang diambil sebelumnya. Misalnya, jika ingin menambahkan item ke array dan tidak ingin kehilangan elemen array yang ada, Anda harus mendapatkan data yang ada terlebih dahulu. Demikian pula, jika API menggunakan ETag, Anda perlu mengirim nilai ETag sebelumnya dengan permintaan agar API berhasil diperbarui.

Catatan: Anda dapat menggunakan header HTTP "If-Match: *" untuk memaksa patch berjalan saat ETag digunakan. Jika Anda melakukannya, Anda tidak perlu melakukan pembacaan sebelum menulis.

Namun, untuk situasi lain, Anda bisa membuat permintaan patch secara langsung, tanpa terlebih dahulu mengambil data yang ada. Misalnya, Anda dapat dengan mudah menyiapkan permintaan patch yang memperbarui kolom ke nilai baru atau menambahkan kolom baru. Berikut contohnya:

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
  }
}

Dengan permintaan ini, jika kolom komentar memiliki nilai yang sudah ada, nilai baru akan menimpanya; jika tidak, kolom ini akan ditetapkan ke nilai baru. Demikian pula, jika ada karakteristik volume, nilainya akan ditimpa; jika tidak, nilai akan dibuat. Kolom akurasi, jika ditetapkan, akan dihapus.

Menangani respons ke patch

Setelah memproses permintaan patch yang valid, API akan menampilkan kode respons HTTP 200 OK bersama dengan representasi lengkap dari resource yang dimodifikasi. Jika ETag digunakan oleh API, server akan memperbarui nilai ETag saat berhasil memproses permintaan patch, seperti yang dilakukan dengan PUT.

Permintaan patch menampilkan seluruh representasi resource kecuali jika Anda menggunakan parameter fields untuk mengurangi jumlah data yang ditampilkannya.

Jika permintaan patch menghasilkan status resource baru yang secara sintaksis atau semantik tidak valid, server akan menampilkan kode status HTTP 400 Bad Request atau 422 Unprocessable Entity, dan status resource tidak akan berubah. Misalnya, jika Anda mencoba menghapus nilai untuk kolom yang wajib diisi, server akan menampilkan error.

Notasi alternatif saat kata kerja HTTP PATCH tidak didukung

Jika firewall Anda tidak mengizinkan permintaan PATCH HTTP, maka lakukan permintaan HTTP POST dan setel header penggantian ke PATCH, seperti yang ditunjukkan di bawah ini:

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

Perbedaan antara patch dan update

Dalam praktiknya, saat mengirim data untuk permintaan update yang menggunakan kata kerja PUT HTTP, Anda hanya perlu mengirim kolom tersebut yang wajib diisi atau opsional; jika Anda mengirim nilai untuk kolom yang ditetapkan oleh server, nilai tersebut akan diabaikan. Meskipun mungkin terlihat seperti cara lain untuk melakukan update sebagian, pendekatan ini memiliki beberapa batasan. Dengan update yang menggunakan kata kerja PUT HTTP, permintaan akan gagal jika Anda tidak memberikan parameter yang diperlukan, dan menghapus sebelumnya data yang ditetapkan jika Anda tidak memberikan parameter opsional.

Lebih aman menggunakan patch karena alasan ini. Anda hanya memberikan data untuk kolom yang ingin diubah; kolom yang Anda hapus tidak akan dihapus. Satu-satunya pengecualian untuk aturan ini terjadi pada elemen atau array berulang: Jika Anda menghilangkan semuanya, elemen tersebut akan tetap apa adanya; jika Anda memberikan salah satunya, seluruh set akan diganti dengan kumpulan yang Anda berikan.