Blogging & Web Terbuka

ID Stabil untuk Entri Feed - Biarkan Post Berubah Tanpa Menjadi Baru Lagi

ID Stabil untuk Entri Feed - Biarkan Post Berubah Tanpa Menjadi Baru Lagi

Sebuah post diterbitkan, dikoreksi keesokan paginya, lalu dipindahkan ke URL yang lebih rapi sebulan kemudian. Bagi pembaca, itu tetap post yang sama. Namun, bagi feed reader, kesinambungan tersebut bergantung pada field kecil yang mudah dibuat ulang tanpa sengaja: identifier entri.

Jika feed generator menurunkan identitas dari judul, timestamp, atau slug saat ini, edit biasa dapat menghasilkan nilai yang berbeda. Sebagian client mungkin kemudian menampilkan revisi itu sebagai entri baru. Kesalahan sebaliknya juga mungkin terjadi: memakai ulang identifier lama untuk konten yang benar-benar baru dapat membuat konten tersebut terlihat seperti update. Bagian tersulitnya bukan menghasilkan string yang tampak unik, melainkan memutuskan arti string tersebut dan mempertahankan maknanya dari waktu ke waktu.

Identitas, lokasi, dan waktu menjawab pertanyaan berbeda

Sebuah entri feed biasanya membawa beberapa nilai yang tampak dapat dipertukarkan, padahal tidak:

  • Identifier: Entri logis yang mana ini?
  • Permalink: Di mana seseorang dapat mengambil representasi web-nya?
  • Waktu publikasi: Kapan entri ini pertama kali tersedia untuk publik?
  • Waktu modifikasi: Kapan representasi ini terakhir direvisi?

Permalink juga dapat berfungsi sebagai identifier, dan itu sering kali merupakan desain yang masuk akal. Namun, kedua peran tersebut tetap berbeda. Redirect dapat memindahkan pengambilan dari URL lama ke URL baru sementara identitas post tidak berubah. Demikian pula, mengoreksi satu paragraf seharusnya mengubah metadata modifikasi, bukan diam-diam membuat entri logis lain.

Bayangkan sebuah buku perpustakaan. Posisi rak memberi tahu di mana buku itu dapat ditemukan; nomor katalog memberi tahu buku mana yang dijelaskan oleh catatan tersebut. Kadang sebuah sistem memakai satu nilai untuk kedua tugas. Masalah dimulai ketika software menganggap memindahkan buku juga harus memberinya identitas baru.

RSS, Atom, dan JSON Feed menyatakan aturan ini secara berbeda

Ketiga format sepakat tentang perlunya kesinambungan, tetapi persyaratannya tidak identik. Meratakannya menjadi satu aturan dapat menghasilkan output yang tidak valid.

RSS 2.0: guid opsional tetapi berguna

Spesifikasi RSS 2.0 mendefinisikan guid sebagai string yang secara unik mengidentifikasi sebuah item. Aggregator dapat memakainya untuk menentukan apakah suatu item baru. Pilihan kata itu penting: RSS tidak menetapkan satu algoritma deduplikasi universal, sehingga publisher tidak dapat menjanjikan perilaku identik di setiap reader.

RSS juga memberi isPermaLink default yang mungkin mengejutkan. Jika atribut tersebut dihilangkan atau bernilai true, nilainya diperlakukan sebagai URL permanen yang terkait dengan item. Karena itu, nilai internal opaque memerlukan isPermaLink="false" secara eksplisit:

<item>
  <title>A Durable Post Title</title>
  <link>https://example.com/posts/durable-title/</link>
  <guid isPermaLink="false">post:1842</guid>
  <pubDate>Sat, 31 Oct 2026 00:00:00 GMT</pubDate>
</item>

Identifier di atas hanyalah contoh string yang dikendalikan publisher. Keunikannya bergantung pada publisher yang tidak pernah memberikan post:1842 kepada item lain dalam feed tersebut. Profil best practice RSS Advisory Board merekomendasikan penyediaan guid untuk setiap item, meskipun format intinya tidak mewajibkan hal itu.

Atom 1.0: atom:id wajib dan permanen

Atom lebih ketat. RFC 4287 bagian 4.2.6 mewajibkan tepat satu atom:id pada setiap entri. Nilainya harus berupa IRI, harus dibuat untuk memastikan keunikan, dan tidak harus dapat dibuka di browser. RFC tersebut secara eksplisit menyatakan bahwa nilainya tidak boleh berubah ketika entri direlokasi, dimigrasikan, disindikasikan, diterbitkan ulang, diekspor, diimpor, atau direvisi.

<entry xmlns="http://www.w3.org/2005/Atom">
  <title>A Durable Post Title</title>
  <id>tag:example.com,2026:post-1842</id>
  <author><name>Example Author</name></author>
  <link rel="alternate"
        href="https://example.com/posts/durable-title/" />
  <published>2026-10-31T00:00:00Z</published>
  <updated>2026-10-31T08:15:00Z</updated>
</entry>

Atom membandingkan ID karakter demi karakter dan secara case-sensitive. Dua string yang kebetulan mengarah ke resource yang sama tetap merupakan ID berbeda jika karakternya berbeda. Karena itu, melakukan normalisasi atau membangun ulang ID pada setiap render berisiko. Dalam Atom, entri dengan atom:id yang sama merepresentasikan entri yang sama; atom:updated menyampaikan waktu revisi.

Contoh tersebut memakai URI tag:. RFC 4151 mendefinisikan scheme ini untuk identifier yang dapat unik tanpa harus bisa diambil. Scheme tersebut menggabungkan authority, tanggal yang terkait dengan authority itu, dan bagian spesifik yang dikelola publisher. Ini adalah salah satu strategi yang tersedia, bukan kewajiban. IRI HTTPS atau IRI valid dan tahan lama lainnya juga dapat memenuhi Atom.

JSON Feed: id dan url adalah field terpisah

JSON Feed 1.1 mewajibkan setiap item memiliki string id yang tetap unik dalam feed tersebut dari waktu ke waktu. Item yang di-update mempertahankan ID-nya, dan item baru tidak boleh memakai ulang ID sebelumnya. url yang opsional adalah permalink. Nilainya boleh sama dengan ID, tetapi format tersebut tetap memisahkan kedua peran secara jelas:

{
  "id": "post:1842",
  "url": "https://example.com/posts/durable-title/",
  "title": "A Durable Post Title",
  "date_published": "2026-10-31T00:00:00Z",
  "date_modified": "2026-10-31T08:15:00Z",
  "content_html": "<p>Corrected content.</p>"
}

JSON Feed menginstruksikan reader untuk membuang item tanpa ID. Ini lebih kuat daripada RSS, tempat guid bersifat opsional. Hal ini menjadi alasan lain untuk tidak memperlakukan format-format tersebut sekadar sebagai serialisasi kosmetik dari satu objek yang didefinisikan secara longgar.

Pilih strategi identifier yang dapat bertahan menghadapi perubahan

Ada dua strategi umum yang sama-sama dapat dipertanggungjawabkan.

Gunakan permalink stabil sebagai ID

Cara ini sederhana dan mudah dibaca manusia. Strategi ini bekerja baik ketika URL yang telah dipublikasikan benar-benar tahan lama, redirect dipelihara, dan migrasi dapat mempertahankan string identifier asli meskipun link saat ini berubah. RSS secara alami mendukungnya melalui perilaku permalink default, dan Atom mengizinkan IRI yang dapat diambil.

Keterbatasannya lebih bersifat organisasional daripada sintaksis. Jika CMS otomatis membangun ulang ID dari domain dan slug saat ini, migrasi domain atau edit slug akan mengubah identitas. ID berbasis URL hanya stabil ketika URL asli yang tersimpan diperlakukan sebagai identitas immutable, bukan dihitung ulang dari konfigurasi routing hari ini.

Gunakan publication ID opaque yang tersimpan

Nilai berbasis database dapat memisahkan identitas dari routing:

feed_entry_id = tag:example.com,2026:post-1842
current_url   = https://example.com/posts/durable-title/

Cara ini membuat perubahan slug dan domain lebih mudah dimodelkan. Namun, strategi ini juga membawa kewajiban: nilai tersebut harus sesuai secara global untuk Atom, unik dalam scope yang dituju, tidak pernah diberikan ulang, dan ikut diekspor saat migrasi. ID opaque tidak otomatis lebih aman hanya karena terlihat teknis. Tanpa penyimpanan tahan lama dan aturan keunikan, nilainya sekadar string mutable lainnya.

CMS praktis dapat membuat identifier satu kali ketika entri pertama kali masuk ke feed publik, menyimpannya dalam kolom khusus yang immutable, dan menampilkan permalink saat ini secara terpisah. Jika CMS menghasilkan beberapa format, mapping untuk masing-masing format perlu didefinisikan secara eksplisit. guid RSS lama boleh berupa string arbitrary ketika ditandai sebagai non-permalink, sedangkan ID Atom harus berupa IRI; menyalin sembarang nilai RSS historis secara buta ke Atom mungkin tidak conform.

Edit dan migrasi membutuhkan kebijakan identitas

Kebijakannya dapat singkat, tetapi sebaiknya menjawab kasus sulit sebelum migration script menjawabnya secara tidak sengaja.

  • Memperbaiki typo atau memperluas bagian: pertahankan entry ID; update metadata modifikasi jika format menyediakannya.
  • Mengubah slug: pertahankan ID; update link saat ini dan pertahankan HTTP redirect jika memungkinkan.
  • Berpindah ke domain lain: pertahankan ID yang sudah dipublikasikan. Entri baru boleh mengikuti kebijakan pembuatan baru, tetapi transisi tidak seharusnya menulis ulang sejarah.
  • Import dari CMS lain: bawa identifier yang sudah ada jika tersedia dan valid untuk format target. Catat mapping yang diperlukan alih-alih menurunkan semuanya dari waktu import.
  • Menerbitkan ulang karya yang secara substansial baru: tentukan secara editorial apakah ini revisi atau entri baru. Publikasi baru harus mendapat ID baru; update harus mempertahankan yang lama.
  • Menghapus lalu memulihkan entri: pulihkan juga ID-nya. Jangan mendaur ulang identifier itu untuk konten yang tidak terkait.

Mengubah kebijakan identifier yang buruk pada feed mapan membutuhkan kehati-hatian. Mengganti setiap ID lama dengan scheme yang lebih rapi dapat membuat entri lama tampak baru di sebagian client. Sering kali pendekatan yang paling sedikit mengganggu adalah mempertahankan nilai historis, menerapkan kebijakan yang diperbaiki untuk entri mendatang, dan memigrasikan ID lama hanya ketika ada alasan spesifik yang sudah diuji.

Validasi feed, lalu periksa perilaku dengan hati-hati

Dokumentasi W3C Feed Validation Service mencantumkan pemeriksaan untuk RSS GUID yang hilang, nilai yang tidak cukup unik, ID Atom duplikat, dan bentuk permalink yang tidak valid. Validasi berguna karena menangkap kesalahan struktural, misalnya menempatkan string RSS arbitrary di bawah interpretasi permalink default.

Validasi tidak dapat membuktikan bagaimana setiap reader akan menampilkan revisi. State client, riwayat import, dan pilihan implementasi tetap berada di luar pandangan syntax validator. Pengujian yang hati-hati memakai feed non-production dan mengamati sebuah urutan: terbitkan satu item, ambil item tersebut, edit konten tanpa mengubah ID, lalu ubah link sambil mempertahankan identitas. Model yang diharapkan adalah satu entri yang berkembang, tetapi klaim tentang reader tertentu harus berasal dari pengujian nyata terhadap reader dan versi tersebut.

Snapshot feed juga layak mendapatkan regression test. Dengan database row yang sama, proses rebuild harus menghasilkan ID yang sama. Mengedit judul atau slug tidak boleh mengubahnya. Membuat row baru tidak boleh memakai ulang nilai milik row yang telah dihapus. Pengujian tersebut melindungi kontrak publikasi secara lebih langsung daripada sekadar memeriksa apakah output memiliki field bernama guid atau id.

Field kecil membawa sejarah

Entry identifier yang tahan lama memungkinkan konten berubah tanpa berpura-pura bahwa entri tersebut telah menjadi sesuatu yang lain. RSS menawarkan guid yang fleksibel dan opsional; Atom mewajibkan IRI permanen; JSON Feed mewajibkan string stabil dalam feed. Sintaksisnya berbeda, tetapi disiplin publikasinya serupa: buat identitas dengan sengaja, simpan, dan jangan menghitungnya ulang dari field yang memang diperkirakan akan berubah.

Tidak ada kebutuhan universal untuk meninggalkan ID berbasis URL, dan nilai opaque juga tidak otomatis lebih baik. Pertanyaan yang berguna lebih sempit: dapatkah nilai persis ini bertahan melewati edit, perubahan route, export, dan migrasi yang secara wajar akan dihadapi publikasi? Jika tidak, identifier tersebut menjelaskan presentasi hari ini, bukan kesinambungan entri.

References