Direktori sekolah, aplikasi PPDB, atau peta faskes — semuanya bertumpu pada satu pola query yang sama.
Tiga dataset referensi tersedia lewat API yang sama: 215.333 sekolah (sumber Dapodik), 4.759 perguruan tinggi (PDDikti), dan 3.116 rumah sakit (SIRS Kemenkes). Polanya identik, jadi apa yang Anda pelajari di satu dataset langsung berlaku di dua lainnya.
Filter, bukan scroll
Dengan 215 ribu baris, menampilkan "semua sekolah" tidak masuk akal. Rancang UI Anda di sekitar filter sejak awal — dan API menyediakan tepat filter yang dibutuhkan:
# SMK swasta di sebuah kabupaten GET /schools?bentuk=SMK&status=S®ency=3204 # cari berdasarkan nama GET /schools?q=SMA Negeri 1 # lookup langsung lewat NPSN GET /schools?npsn=20106343
Filter bisa digabung bebas, dan setiap respons membawa total — angka itulah yang Anda pakai untuk paginasi dan untuk memberi tahu pengguna seberapa lebar hasilnya.
Bentuk responsnya
{
"status": "success",
"total": 749,
"page": 1,
"per_page": 100,
"total_pages": 8,
"count": 100,
"source": "Dapodik/Kemdikbud",
"data": [
{
"npsn": "20106343",
"name": "SMA NEGERI 1 CIAWIGEBANG",
"bentuk": "SMA",
"status": "N",
"province": "Jawa Barat",
"regency": "Kab. Kuningan",
"district": "Ciawigebang",
"address": "Jl. Siliwangi No. 1",
"lat": -6.974,
"lng": 108.5894
}
]
}Koordinat membuka fitur peta
Sebagian besar baris sekolah membawa lat dan lng, yang langsung mengubah direktori teks menjadi peta. Beberapa baris bernilai null — data Dapodik tidak lengkap untuk semua sekolah — jadi selalu tangani kasus itu alih-alih mengasumsikan koordinat selalu ada:
const res = await fetch('/api/proxy/schools?bentuk=SMA®ency=3204&per_page=500');
const { data } = await res.json();
data
.filter((s) => s.lat !== null && s.lng !== null) // lewati yang tanpa koordinat
.forEach((s) => {
L.marker([s.lat, s.lng])
.bindPopup(`<strong>${s.name}</strong><br>${s.address ?? ''}`)
.addTo(peta);
});Paginasi tanpa membuat pengguna menunggu
Batas per_page adalah 500. Untuk daftar panjang, ambil halaman pertama secepatnya lalu muat sisanya di latar belakang — pengguna melihat hasil dalam sekejap, bukan menatap spinner.
async function ambilSemua(query) {
const pertama = await get(`${query}&page=1&per_page=500`);
render(pertama.data); // tampilkan segera
const sisa = [];
for (let p = 2; p <= pertama.total_pages; p++) {
sisa.push(get(`${query}&page=${p}&per_page=500`));
}
const halaman = await Promise.all(sisa); // muat paralel
halaman.forEach((h) => render(h.data));
}Universitas dan rumah sakit
Kedua dataset lain memakai pola query yang sama, hanya dengan filter yang sesuai domainnya:
# politeknik negeri GET /universities?q=politeknik negeri # rumah sakit jiwa di Jawa Barat GET /hospitals?type=RS Jiwa&province=32
Siap mencoba?
Buat akun gratis dan dapatkan API key — 5.000 hits gratis per bulan, dan dua endpoint yang tak butuh key sama sekali.