Gerbang Validasi Sebelum Foto Pihak Ketiga Masuk Grid
Nama dicocokkan dulu, gambar dicek setelah selesai dimuat, yang ragu dikembalikan. Begitu bentuk gerbang validasi untuk foto pihak ketiga.
Ringkasan
Data entitas budaya ada, tapi foto tidak ada. Saya ambil foto dari Google Maps, tapi harus dicek dulu. Identitas dan gambar harus valid.
Sore itu saya menatap grid budaya di KotaPortal yang tampil setengah kosong: kartu-kartu ada, judulnya ada, gambarnya nol. Data entitas sehat di API, jadi masalahnya murni pasokan foto. Pemilik tempat punya foto di Google Maps. Solusi tercepat yang terbayar: buka halaman Maps-nya, ambil gambar hero pertama, unduh versi =w1200, simpan lokal, isi kolom gambar. Beres dalam satu sore, begitu perkiraan saya.
Kenyataan bicara lebih dulu. Di tengah proses, saya menemukan entitas budaya yang fotonya ternyata toko furniture, satu lagi interior mal, dan satu lagi foto dari kota yang salah. Namanya mirip di pencarian, halamannya beda total. Kalau ini lolos, pembaca akan memercayai grid itu dan mendapat informasi yang salah tanpa pernah tahu.
Nama dulu, gambar belakangan
Gerbang pertama bukan soal gambar, tapi identitas: judul halaman Maps harus persis sama dengan nama entitas di database sebelum foto diterima. Terdengar kaku, tapi kesalahan mapping yang lolos jauh lebih mahal daripada kartu kosong. Dari 12 entitas yang diproses, 7 lolos dan disimpan, 5 saya kembalikan ke tampilan tanpa gambar karena tidak bisa diverifikasi. Satu dari kesalahan tadi berhasil dipulihkan lewat query ulang; sisanya tidak. Dan di ronde ketiga, Google mulai membatasi laju permintaan. Batas itu bukan penghambat, tapi sinyal untuk berhenti menebak.
Setelah lolos gerbang nama, baru pemeriksaan teknis gambar. Sinyal yang saya pakai satu: naturalWidth === 0. Properti naturalWidth mengembalikan lebar intrinsik gambar dalam piksel CSS [4], dan nilainya nol saat data gambar tidak tersedia: artinya gambar rusak atau kosong. Syaratnya satu kalimat: cek dilakukan setelah event load atau error selesai, bukan di tengah pemuatan, kalau tidak gambar lambat akan salah dilabeli rusak. Thumbnail grid juga saya beri loading="lazy": sumber daya non-kritis ditunda sampai mendekati area pandang [2], jadi 12 kartu tidak berarti 12 unduhan di detik pertama.
URL Google itu pipa, bukan gudang
Asumsi yang ikut runtuh: tautan foto Google itu permanen. Saluran resminya saja menolak anggapan itu: photo_reference tidak boleh di-cache dan bisa kedaluwarsa [3]. URL foto adalah pipa tampilan, bukan gudang penyimpanan.
Bagian yang paling jujur untuk diakui: menyimpan salinan lokal foto Maps sama dengan mengeluarkan konten dari layanannya. Ketentuan penggunaannya tegas, "Customer will not export, extract, or otherwise scrape Google Maps Content for use outside the Services" [1]. Google bahkan memberi sinyal visual soal asal foto: nama atau ikon atribusi membedakan foto yang diambil Google dari foto kontributor eksternal [5]. Artinya praktis: foto hasil backfill seperti ini jembatan darurat, bukan aset permanen. Ganti bertahap dengan foto resmi dari pemilik bidang, dan catat jujur di log bahwa lisensinya belum jelas.
Perubahan massal butuh rem
Mengisi belasan baris data dalam satu sesi adalah operasi massal, dan operasi massal tanpa rem cuma menunggu tanggal jadi cerita horor. Rem yang saya pasang tiga lapis. Dump SQL sebelum eksekusi, jalur kembali yang bisa dibaca manusia, bukan cuma log. Hitung ulang lewat API setelahnya: 7 entitas bawa gambar, sisanya kembali ke tampilan tabel. Terakhir, verifikasi visual per kartu, nama di layar dicocokkan dengan isi fotonya, satu per satu, bukan dicek asal ada gambarnya.
Satu jebakan kecil yang nyaris lolos: payload list API menaruh gambar di field thumbnail, bukan di field gambar utama. Konsumen API berikutnya yang berasumsi akan menggambar grid kosong, persis masalah yang mencetuskan pekerjaan ini.
Foto pihak ketiga itu murah, sampai salah satu fotonya salah. Gerbang validasi (nama dulu, gambar dicek setelah selesai dimuat, kembalikan kalau ragu, dump sebelum eksekusi massal) bukan birokrasi tambahan. Itu harga murah untuk grid yang pantas dipercaya.
Sources
[1] Google Maps Platform Terms of Service · [2] MDN: Lazy loading · [3] Google Place Photos (Legacy) · [4] MDN: HTMLImageElement.naturalWidth · [5] Maps User Contributed Content Policy