Panduan HTTP

Dokumen ini menjelaskan cara kerja Google API dengan berbagai versi dan implementasi HTTP. Jika menggunakan salah satu library klien kami yang dibuat atau dibuat secara manual (pendekatan yang kami rekomendasikan untuk sebagian besar kasus penggunaan), Anda tidak perlu khawatir tentang hal ini, karena kode yang diberikan berkaitan dengan masalah tingkat rendah terkait komunikasi dengan server.

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

Bekerja dengan protokol kabel (HTTP/*)

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

Semantik HTTP

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

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 caching.

Versi HTTP

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

Beberapa fitur API mungkin hanya didukung oleh protokol HTTP versi baru, seperti server-push dan prioritas. Beberapa fitur 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.

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

Saluran

Saluran merujuk pada koneksi jaringan L4 (soket TCP atau UDP). Aplikasi klien tidak boleh membuat asumsi tentang cara saluran digunakan selama runtime untuk menyalurkan permintaan HTTP. Di hampir semua kasus, saluran dihentikan oleh proxy atas nama proses server.

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

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

HTTPS

Klien dapat mengakses API melalui HTTPS atau HTTP, seperti yang didukung oleh spesifikasi API. Negosiasi TLS dan versi TLS 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 dan 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 berapa pun pesan JSON atau pesan JSON status error.

URL Permintaan Panjang

URL memiliki batasan panjang praktis, biasanya antara 2k hingga 8k. Cara ini diterapkan oleh beberapa browser dan {i>proxy<i}. Jika API Anda menggunakan permintaan GET dengan URL yang melebihi batas panjang, permintaan tersebut dapat ditolak oleh browser. Untuk mengabaikan batasan ini, kode klien harus menggunakan permintaan POST dengan Jenis Konten 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 akan ditentukan sebagai bagian dari spesifikasi API. Secara khusus, setiap metode API harus mematuhi persyaratan protokol HTTP berdasarkan Verb HTTP tertentu yang dipetakan metode API. Untuk mengetahui detailnya, lihat spesifikasi Hypertext Transfer Protocol dan RFC Metode PATCH.

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

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

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

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

Format Payload

  • Permintaan dan respons harus memiliki Jenis Konten yang sama, kecuali jika permintaan tersebut berupa GET atau POST dengan isi "application/x-www-form-urlencoded".

  • JSON didukung berdasarkan jenis MIME application/json. Pemetaan dari proto3 ke JSON secara resmi ditentukan 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

{i>Half-duplex<i} vs {i>full-duplex<i}

HTTP adalah protokol respons permintaan yang memungkinkan isi permintaan atau responsnya dikirim melalui transpor berorientasi streaming yang berbeda seperti TCP (HTTP/1.x) atau varian multipleksnya (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) ketika 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 apa pun, Cloud API berbasis HTTP dibatasi hanya untuk streaming half-duplex.

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

Untuk klien browser, semantik HTTP standar lebih dibatasi oleh API Jaringan browser. Saat ini, browser hanya mendukung streaming server (yang umumnya mematuhi framing level transport) melalui XHR atau Fetch. Fetch API menggunakan 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, {i>client-streaming<i} melalui Internet kurang berguna dibandingkan dengan {i>server-streaming<i}. Hal ini karena penggunaan streaming klien sering kali mengarah ke layanan stateful, yang berpengaruh buruk pada load balancing dan membuat sistem lebih rentan terhadap kegagalan atau serangan. Di sisi lain, streaming server dapat bermanfaat karena dapat secara signifikan mengurangi latensi pada 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 kabel: definisi StreamBody hanya signifikan dalam alokasi ID tagnya untuk kolom "messages" dan "status" akan bervariasi dengan 1-2 byte untuk pesan normal, sehingga total overhead encoding adalah 2-3 byte per pesan.

Kolom padding opsional diperlukan untuk mendukung streaming berenkode 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, dengan format yang sama seperti pesan biasa.

Pengelolaan Status

Perilaku setengah dekat ditentukan dengan baik dalam setiap versi HTTP agar klien atau server memberi tahu pihak lain bahwa isi telah selesai.

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

Pembatalan

Dukungan pembatalan memungkinkan klien untuk membatalkan permintaan saat permintaan atau respons masih menunggu keputusan.

Tidak ada dukungan pembatalan yang dapat diandalkan untuk klien HTTP/1.*, karena klien bebas menutup koneksi TCP setelah permintaan selesai tanpa membatalkan transaksi permintaan/respons. TCP FIN, di bawah HTTP/1.1, tidak boleh diinterpretasikan sebagai pembatalan, bahkan jika koneksi ditandai sebagai 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 menjadi masalah untuk API non-streaming. Terutama, ketika respons melibatkan polling yang lama, sehingga koneksi mungkin tetap tidak ada aktivitas dalam jangka waktu yang lama.

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

Tetap hidup

Dukungan Keep-alive memungkinkan klien atau server mendeteksi peer yang gagal, bahkan jika paket hilang atau kegagalan jaringan.

Tidak ada dukungan keep-alive di HTTP/1.1 karena TCP keep-alive bukanlah pendekatan yang tepat.

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

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

Kontrol Aliran

Dukungan kontrol alur mengharuskan klien untuk menerapkan peristiwa kontrol alur tingkat transport ke aplikasi klien. Mekanisme sebenarnya bergantung pada gaya API klien HTTP yang digunakan aplikasi klien Anda. Misalnya, Anda perlu memblokir operasi tulis dan baca, atau operasi baca dan tulis yang tidak memblokir dengan dukungan kontrol alur eksplisit agar aplikasi dapat menangani dan mematuhi peristiwa kontrol alur, untuk mencegah klien atau server mengalami kelebihan beban.

HTTP/1.1 mengandalkan kontrol alur TCP.

SPDY dan HTTP/2 memiliki kontrol alur sendiri di level aliran data, yang selanjutnya tunduk pada kontrol alur TCP di tingkat koneksi karena permintaan dimultipleks melalui satu koneksi TCP.

QUIC berjalan di UDP sehingga mengelola kontrol alur sepenuhnya sendiri.