Pedoman HTTP

Dokumen ini menjelaskan cara kerja Google API dengan berbagai versi dan penerapan HTTP. Jika Anda menggunakan salah satu library klien buatan tangan atau yang dihasilkan (pendekatan yang kami rekomendasikan untuk sebagian besar kasus penggunaan), Anda tidak perlu khawatir tentang hal ini, karena kode yang disediakan menangani masalah tingkat rendah dalam berkomunikasi dengan server.

Namun, jika Anda adalah developer berpengalaman dan perlu menulis kode kustom Anda sendiri untuk mengakses antarmuka REST API secara langsung menggunakan library klien HTTP pihak ketiga pilihan Anda, Anda harus memahami setidaknya beberapa semantik yang didokumentasikan di sini (sebagaimana relevan dengan API yang Anda pilih), serta memahami apa yang disediakan oleh library HTTP Anda.

Menggunakan protokol kabel (HTTP/*)

Bagian ini menjelaskan protokol jaringan yang didukung (biasanya versi HTTP) yang dapat digunakan Cloud API untuk berkomunikasi antara klien dan server, serta cara kami merekomendasikan Anda menggunakannya. Kita akan melihat detail tentang cara penyusunan permintaan dan respons di bagian berikutnya di bawah.

Semantik HTTP

Saat mengembangkan kode klien API, ikuti semantik protokol HTTP standar. Proxy sisi server atau stack API mungkin hanya mendukung sebagian fitur HTTP standar, dan juga dapat mendukung versi yang kompatibel dengan versi sebelumnya.

Semantik protokol HTTP yang perlu ditangani oleh implementasi API sisi server dikontrol oleh stack server. Hanya mengandalkan semantik tersebut jika fitur ini didokumentasikan secara eksplisit sebagai bagian dari spesifikasi API, seperti dukungan penyimpanan dalam cache.

Versi HTTP

Klien dapat menggunakan protokol HTTP/* apa pun, sebagaimana diizinkan oleh platform klien atau jaringan sisi klien mereka, atau sebagaimana dinegosiasikan dengan proxy sisi server. Protokol yang didukung mencakup HTTP/1.0, HTTP/1.1, SPDY/*, HTTP/2, dan QUIC.

Beberapa fitur API mungkin hanya didukung oleh protokol HTTP versi yang lebih baru, seperti server-push dan prioritas; beberapa hanya ditentukan sepenuhnya dengan HTTP/2, seperti streaming full-duplex. Perhatikan batasan versi HTTP yang berbeda jika Anda memerlukan salah satu fitur ini sebagai bagian dari spesifikasi API.

Secara umum, kami merekomendasikan HTTP/2 untuk performa yang lebih baik serta ketahanan terhadap kegagalan jaringan.

Saluran

Saluran mengacu pada koneksi jaringan L4 (soket TCP atau UDP). Aplikasi klien tidak boleh membuat asumsi apa pun tentang cara saluran digunakan dalam runtime untuk menayangkan permintaan HTTP. Dalam hampir semua kasus, saluran dihentikan oleh proxy atas nama proses server.

Untuk klien HTTP/1.1, selalu gunakan kembali koneksi TCP (Connection: Keep-Alive); library klien HTTP kemungkinan juga akan mengelola kumpulan koneksi untuk performa yang lebih baik. Jangan membuat pipeline permintaan melalui koneksi TCP yang sama. Lihat HTTP dan TCP untuk informasi lebih lanjut.

Semua browser modern menggunakan SPDY/*, HTTP/2, atau QUIC, yang melakukan multiplexing permintaan melalui satu saluran. Batas koneksi tradisional (2-10) tidak boleh menjadi masalah kecuali jika implementasi server membatasi jumlah permintaan HTTP serentak dari satu klien, misalnya, 100 streaming HTTP/2 terhadap satu origin.

HTTPS

Klien dapat mengakses API melalui HTTPS atau HTTP, seperti yang didukung oleh spec API. Negosiasi TLS dan versi TLS bersifat transparan untuk aplikasi klien. Secara default, Google API hanya menerima traffic HTTPS.

Format Permintaan/Respons

URL Permintaan

Pemetaan JSON-REST mendukung data permintaan yang dienkode URL, dan isi permintaan serta respons HTTP menggunakan application/json sebagai Content-Type.

Isi HTTP menggunakan array JSON untuk mendukung metode RPC yang di-streaming, dan array JSON dapat berisi pesan JSON dalam jumlah berapa pun atau pesan JSON status error.

URL Permintaan Panjang

URL memiliki batasan panjang yang praktis, biasanya ditetapkan ke 16 KB secara default, meskipun hal ini dapat bervariasi bergantung pada server. Jika API Anda menggunakan permintaan GET dengan URL yang melebihi panjang ini, permintaan mungkin tidak menjangkau server API tujuan dan akan ditolak oleh Google Front End (GFE) dengan pesan error Your client has issued a malformed or illegal request.

Untuk mengabaikan batasan tersebut, kode klien harus menggunakan permintaan POST dengan Content-Type application/x-www-form-urlencoded beserta header HTTP X-HTTP-Method-Override: GET. Pendekatan ini juga berfungsi untuk permintaan DELETE.

Metode HTTP (Kata Kerja)

Jika URL permintaan mengikuti model REST, metode HTTP-nya ditentukan sebagai bagian dari spesifikasi API. Secara khusus, setiap metode API harus mematuhi persyaratan protokol HTTP berdasarkan Verb HTTP tertentu yang dipetakan oleh metode API. Untuk mengetahui detailnya, baca spesifikasi Hypertext Transfer Protocol dan RFC Metode PATCH.

Metode Aman, seperti GET dan HEAD HTTP tidak boleh mewakili tindakan selain pengambilan. Secara khusus, HTTP GET harus dianggap aman dan tidak boleh memiliki efek samping yang terlihat oleh klien.

Idempotensi di HTTP berarti bahwa efek samping dari beberapa permintaan yang identik sama dengan untuk satu permintaan. GET, PUT, dan DELETE adalah metode HTTP idempoten yang relevan dengan panduan gaya. Perhatikan bahwa idempotence hanya dinyatakan dalam hal efek samping sisi server dan tidak menentukan apa pun tentang respons. Khususnya, DELETE untuk resource yang tidak ada harus menampilkan 404 (Not Found).

POST dan PATCH HTTP tidak aman atau idempoten. (PATCH diperkenalkan dalam RFC 5789)

Verb HTTP Aman Idempotent
GET Ya Ya
PUT   Ya
DELETE   Ya
POST  
PATCH  

Format Payload

  • Permintaan dan respons harus memiliki Content-Type yang sama, kecuali jika permintaan adalah GET atau POST dengan isi "application/x-www-form-urlencoded.

  • JSON didukung dalam jenis MIME application/json. Pemetaan dari proto3 ke JSON ditentukan secara formal dalam Pemetaan JSON.

  • Parameter formulir (POST) dapat digunakan sebagai pengganti parameter kueri URL (GET), dengan mengikuti aturan pemetaan gaya REST yang sama untuk memetakan kolom permintaan ke parameter kueri. Content-Type yang didukung adalah application/x-www-form-urlencoded.

Streaming

Half-duplex versus full-duplex

HTTP adalah protokol permintaan-respons yang memungkinkan isi permintaan atau responsnya dikirim melalui berbagai transpor berorientasi streaming seperti TCP (HTTP/1.x) atau varian multiplex-nya (SPDY, HTTP/2, QUIC).

Sebagai developer klien, aplikasi Anda dapat menghasilkan isi permintaan dalam mode streaming, yaitu streaming klien. Demikian pula, aplikasi juga dapat menggunakan isi respons dalam mode streaming, yaitu streaming server.

Namun, spesifikasi HTTP tidak menentukan apakah server diizinkan untuk melakukan streaming kembali isi respons (kecuali untuk respons error) saat isi permintaan masih tertunda. Semantik ini dikenal sebagai streaming full-duplex. Meskipun banyak software klien/server/proxy HTTP mengizinkan streaming full-duplex, bahkan untuk HTTP/1.1, untuk menghindari masalah interoperabilitas, Cloud API berbasis HTTP dibatasi untuk streaming half-duplex saja.

Secara default, metode streaming bidi di Cloud API mengasumsikan semantik full-duplex. Artinya, tidak aman menggunakan HTTP untuk memanggil metode tersebut. Jika metode streaming hanya half-duplex (seperti yang diterapkan oleh server), dokumen API harus menentukan perilaku half-duplex dengan jelas.

Untuk klien browser, semantik HTTP standar lebih dibatasi oleh Network API browser. Saat ini, browser hanya mendukung streaming server (yang umumnya mematuhi framing tingkat transpor) melalui XHR atau Fetch. Fetch API membuat penggunaan streaming whatwg.

Karena pembatasan browser, Cloud API yang memerlukan dukungan browser harus menghindari streaming klien serta streaming full-duplex, atau menyediakan API terpisah khusus untuk klien browser.

Secara umum, streaming klien melalui Internet kurang berguna daripada streaming server. Hal ini karena penggunaan streaming klien sering kali menyebabkan layanan stateful, yang berdampak buruk pada load balancing dan membuat sistem lebih rentan terhadap kegagalan atau serangan. Di sisi lain, streaming server dapat berguna karena dapat mengurangi latensi secara signifikan melalui jaringan dengan penundaan RTT yang lama.

Encoding Pesan

Pesan JSON saat streaming dienkode sebagai array pesan JSON. Isi permintaan atau respons akan tetap sebagai jenis MIME JSON yang valid.

Contoh encoding streaming klien:

1 <length> <message-bytes> 1 <length> <message-bytes>   EOF

Contoh encoding streaming server:

1 <length> <message-bytes>   2 <length> <status-bytes> EOF

Encoding tingkat wire: definisi StreamBody hanya signifikan dalam alokasi ID tag untuk kolom "messages" dan "status" akan dienkode varint dengan 1-2 byte untuk pesan normal, sehingga total overhead encoding adalah 2-3 byte per pesan.

Kolom padding opsional diperlukan untuk mendukung streaming yang dienkode base64:

message StreamBody {
  repeated bytes message = 1;
  google.rpc.Status status = 2;
  repeated bytes padding = 15;   // max one-byte tag-id: xxx01111
}

Pesan error harus ditambahkan sebagai elemen terakhir dari array JSON atau protobuf, dalam format yang sama dengan pesan reguler.

Pengelolaan Status

Perilaku setengah tertutup ditentukan dengan baik dalam versi HTTP apa pun untuk klien atau server guna memberikan sinyal ke ujung lain bahwa isi telah selesai.

Secara khusus, kode klien bebas menyelesaikan permintaan saat masih menunggu respons. Demikian pula, klien mungkin melihat respons yang sudah selesai saat isi permintaan masih ditulis ke server. Standar HTTP mengharapkan klien membatalkan atau menyelesaikan permintaan saat respons selesai dengan cara yang tidak terduga, biasanya dengan status error. Artinya, dalam kondisi normal, server tidak boleh menyelesaikan respons saat klien masih mengirim permintaan.

Pembatalan

Dukungan pembatalan memungkinkan klien membatalkan permintaan saat permintaan atau respons masih tertunda.

Tidak ada dukungan pembatalan yang andal untuk klien HTTP/1.*, karena klien bebas menutup koneksi TCP setelah permintaan selesai tanpa membatalkan transaksi permintaan/respons. TCP FIN, dalam HTTP/1.1, tidak boleh ditafsirkan sebagai pembatalan, meskipun koneksi ditandai sebagai koneksi keep-alive (Connection: Keep-Alive).

Namun, setelah klien menutup koneksi TCP, jika server mencoba menulis data apa pun ke klien, RST akan dibuat, yang dapat memicu pembatalan.

Perhatikan juga bahwa pembatalan juga merupakan masalah untuk API non-streaming. Hal ini terutama terjadi jika respons melibatkan polling yang lama sehingga koneksi dapat tetap tidak ada aktivitas selama jangka waktu yang lama.

Pembatalan eksplisit didukung dengan SPDY, HTTP/2, dan QUIC, terutama dengan pesan go-away.

Keep-alive

Dukungan keep-alive memungkinkan klien atau server mendeteksi peer yang gagal, bahkan saat terjadi kehilangan paket atau kegagalan jaringan.

Tidak ada dukungan keep-alive di HTTP/1.1 karena keep-alive TCP bukan pendekatan yang layak.

QUIC atau HTTP/2 menawarkan pesan kontrol khusus untuk tujuan menerapkan dukungan keep-alive oleh aplikasi, termasuk browser.

Namun, deteksi kegagalan dan keep-alive yang andal kemungkinan akan memerlukan library klien dengan dukungan sisi server yang diperlukan: melakukan streaming berdurasi lama melalui internet sering kali rentan error saat mengandalkan HTTP dasar sebagai protokol komunikasi.

Kontrol Aliran

Dukungan kontrol alur mengharuskan klien untuk menyebarkan peristiwa kontrol alur tingkat transpor ke aplikasi klien. Mekanisme sebenarnya bergantung pada gaya API klien HTTP yang digunakan aplikasi klien Anda. Misalnya, Anda memerlukan operasi tulis dan baca pemblokiran, atau operasi baca dan tulis non-pemblokiran dengan dukungan kontrol alur eksplisit agar aplikasi dapat menangani dan mematuhi peristiwa kontrol alur, untuk mencegah klien atau server kelebihan beban.

HTTP/1.1 mengandalkan kontrol alur TCP.

SPDY dan HTTP/2 memiliki kontrol alur sendiri di tingkat streaming, yang selanjutnya tunduk pada kontrol alur TCP di tingkat koneksi saat permintaan di-multiplex melalui satu koneksi TCP.

QUIC berjalan di UDP sehingga dapat mengelola kontrol alur sepenuhnya sendiri.