Pengembangan Web

Header HTTP Vary — Agar Response yang Berbeda Tidak Saling Tertukar

Header HTTP Vary — Agar Response yang Berbeda Tidak Saling Tertukar

Header HTTP Vary — Agar Response yang Berbeda Tidak Saling Tertukar

Satu URL tidak selalu menghasilkan response yang persis sama. Server dapat memilih representasi berdasarkan bahasa, format kompresi, atau media type yang diterima request. Fleksibilitas ini berguna, tetapi menimbulkan pertanyaan bagi setiap cache: kapan response dari satu request boleh dipakai untuk request lain?

Response header HTTP Vary adalah bagian dari jawabannya. Header ini tidak mengaktifkan caching, tidak menentukan masa berlaku, dan tidak memilih representasi terbaik. Tugasnya adalah memberi tahu cache request header mana yang memengaruhi response, sehingga cache tidak menganggap variant yang berbeda sebagai hal yang sama.

Satu Resource, Beberapa Representasi

HTTP membedakan resource dari representasi resource tersebut. Satu URL dapat memiliki beberapa representasi: dokumen HTML dalam beberapa bahasa, response terkompresi atau tidak terkompresi, atau gambar yang dipilih dari preferensi client.

Ini disebut server-driven atau proactive content negotiation. Client mengirim petunjuk seperti Accept, Accept-Encoding, atau Accept-Language. Server menjalankan algoritmanya sendiri lalu mengirim satu representasi. Panduan content negotiation MDN menekankan batas penting: algoritmanya ditentukan server. Adanya preferensi di request tidak otomatis menentukan representasi yang harus dipilih server.

Misalnya, request ke /guide dengan Accept-Language: id dapat menerima HTML Indonesia. Request lain ke URL yang sama dengan Accept-Language: en dapat menerima HTML Inggris. URL-nya sama, tetapi response-nya berbeda.

Apa yang Dijelaskan oleh Vary

Vary adalah response header. Nilainya mencantumkan request-header field yang memengaruhi response. Contoh sederhananya:

HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
Vary: Accept-Language

<html>...</html>

Artinya, pemilihan response bergantung pada Accept-Language. Ini tidak berarti semua bahasa tersedia dan tidak memberi tahu cache algoritma pemilihan bahasa server. Header ini hanya menunjukkan input yang harus dipertimbangkan cache ketika memutuskan apakah response tersimpan boleh digunakan kembali.

Gagasan yang sama berlaku untuk kompresi:

Vary: Accept-Encoding

Jika server mengirim representasi terkompresi ketika client menerima Brotli dan representasi lain dalam kondisi berbeda, request tersebut tidak boleh diperlakukan sebagai variant yang sama hanya karena URL dan method-nya sama.

Definisi formalnya ada di RFC 9110, Section 12.5.5. Ringkasan praktis dari referensi Vary MDN juga jelas: header ini menjelaskan bagian request, selain method dan URL, yang memengaruhi response.

Bagaimana Cache Menggunakannya

Cache memerlukan setidaknya method request dan target URI untuk menemukan response tersimpan. Jika response memiliki Vary: Accept-Language, itu belum cukup. Cache juga membandingkan field Accept-Language pada request baru dengan field pada request yang menghasilkan response tersimpan.

RFC 9111, Section 4.1 menjelaskan ini sebagai syarat pencocokan. Jika field yang disebut tidak cocok, cache tidak boleh menggunakan response tersimpan tanpa revalidasi. Cache biasanya perlu mencari response variant lain atau meneruskan request ke origin.

Model mental yang berguna:

  1. URL mengidentifikasi resource.
  2. Nilai Vary pada response menyebutkan field request yang memengaruhi pemilihan representasi.
  3. Cache membandingkan field tersebut sebelum memakai response kembali.
  4. Hanya response yang cocok dan memang boleh digunakan kembali yang dapat menjawab request baru.

Ini tidak persis sama dengan mengatakan bahwa setiap cache membuat string cache key dari URL dan nilai header. Implementasi internal bisa berbeda. Yang diwajibkan protokol adalah kelayakan response tersimpan untuk dipakai kembali, bukan struktur data tertentu.

Response Default Juga Penting

Kesalahan yang sering terjadi adalah menambahkan Vary hanya ketika request secara eksplisit membawa preferensi. Misalnya server mengirim bahasa default ketika Accept-Language tidak ada, tetapi mengirim bahasa lain ketika field tersebut ada. Response default tetap dihasilkan oleh kebijakan pemilihan yang sama.

Karena itu, nilai Vary sebaiknya konsisten untuk response pada suatu URL, termasuk response default. Spesifikasi caching memperingatkan bahwa menghilangkan header dari response default dapat membuat response tersebut dipilih untuk request berikutnya walaupun variant lain lebih sesuai.

Hal yang sama berlaku untuk response 304 Not Modified. Response validator tidak membawa body representasi baru, tetapi metadatanya ikut dalam proses pembaruan cache. Menjaga metadata Vary tetap konsisten bukan detail kosmetik.

Apa Arti Vary: *?

Wildcard memiliki arti yang lebih khusus:

Vary: *

Nilai ini menunjukkan bahwa informasi selain request header yang disebut memengaruhi response. Cache tidak dapat mengulang pemilihan tersebut hanya dengan mencocokkan request header. Aturan HTTP caching memperlakukan response tersimpan dengan wildcard ini sebagai variant yang gagal dalam pencocokan normal.

Wildcard bukan cara umum untuk menuliskan banyak header. Jika Accept dan Accept-Encoding memengaruhi response, sebutkan keduanya:

Vary: Accept, Accept-Encoding

Sebaliknya, menambahkan banyak header dengan variasi tinggi dapat menciptakan terlalu banyak variant dan mengurangi manfaat shared cache. MDN mencatat bahwa server-driven negotiation dapat membuat shared cache kurang efisien dan mengekspos lebih banyak informasi preferensi client. Nilai terbaik bukan daftar terpanjang, melainkan daftar terkecil yang akurat.

Language Negotiation Bukan Preferensi yang Sempurna

Accept-Language tampak praktis untuk website multilingual, tetapi sebaiknya dianggap sebagai petunjuk. Nilai browser sering mencerminkan bahasa antarmuka, bukan bahasa yang diinginkan untuk semua website. Seseorang juga dapat memakai perangkat bersama atau memahami beberapa bahasa.

MDN menyarankan agar pembaca diberi cara untuk mengganti pilihan server, misalnya melalui menu bahasa, lalu pilihan eksplisit itu dihormati. Ini keputusan produk dan arsitektur informasi, bukan masalah yang dapat diselesaikan oleh Vary.

Untuk situs dengan URL bahasa yang stabil, seperti /en/guide, /id/panduan, dan /de/anleitung, URL dapat membuat representasi yang dipilih lebih jelas. Pendekatan ini dapat mengurangi ambiguitas bagi pembaca, link, bookmark, dan cache. Ini tidak otomatis lebih baik untuk semua aplikasi, tetapi sering lebih mudah dipahami daripada mengubah satu URL secara diam-diam berdasarkan petunjuk browser.

Checklist Review

Saat meninjau response yang dinegosiasikan, aku akan menanyakan hal-hal berikut tanpa menganggap framework atau CDN tertentu sudah mengambil keputusan yang benar:

  • Apakah satu URL dapat mengembalikan representasi yang berbeda secara bermakna?
  • Field request mana yang benar-benar memengaruhi pemilihan?
  • Apakah response mencantumkan field tersebut dalam Vary?
  • Apakah response default memakai metadata relevan yang sama?
  • Apakah response 304 mempertahankan informasi Vary yang diperlukan?
  • Apakah URL eksplisit atau pilihan bahasa pengguna akan lebih jelas daripada negotiation otomatis?
  • Apakah response privat atau sensitif dipertimbangkan terpisah dari variant publik biasa?

Checklist ini tidak dapat membuktikan konfigurasi cache production benar. Reverse proxy, CDN, framework aplikasi, dan browser dapat memiliki kebijakan masing-masing. Ini adalah titik awal untuk melacak response header yang benar-benar dikirim dan dimensi request yang dipakai aplikasi.

Kesimpulan

Vary mudah terlewat karena tidak mengubah body yang dilihat pembaca. Tugasnya adalah menjelaskan mengapa body itu dipilih, agar intermediary tidak menggunakannya untuk request yang tidak cocok. Jadi, ia lebih dulu merupakan sinyal correctness sebelum menjadi fitur performance.

Pelajaran praktisnya sederhana: jika response berubah karena request header, buat ketergantungan itu terlihat. Gunakan URL bahasa atau pilihan pengguna yang eksplisit jika keduanya membuat sistem lebih mudah dipahami. Jika perilaku bergantung pada faktor yang tidak bisa diwakili request header, jangan menganggap cache dapat menebaknya hanya dari URL.

References