# Bagaimana Cara Mencari Henti Transportasi Terdekat dengan API?

> Pelajari cara mencari henti terdekat menggunakan API ROOTE: koordinat, radius, contoh JavaScript, membaca hasil, dan penanganan kesalahan.

Source: https://www.roote.ai/id/guides/cara-mencari-henti-transit-terdekat-dengan-api/
Language: id
Author: ROOTE

Untuk mencari henti di sekitar suatu titik, kirimkan latitude, longitude, dan radius ke API lokasi terdekat. Periksa status respons, entitas yang dikembalikan, dan informasi cakupan sebelum menampilkan daftar atau peta.

Dalam kontrak ROOTE roote-1.0.0, rute GET /v1/transit/nearby menemukan lokasi transportasi di sekitar. Ini tidak mengambil keberangkatan atau peringatan waktu nyata. Pencarian lokasi dan pencarian keberangkatan berikutnya adalah dua operasi terpisah.

## Mendefinisikan parameter

Permintaan menggunakan lat untuk latitude dan lng untuk longitude. Alias lon juga dijelaskan dalam kontrak. Parameter radius menunjukkan jangkauan dalam meter; limit membatasi jumlah hasil yang diminta. Filter modes dapat menentukan moda transportasi.

| Parameter | Contoh | Arah |
| --- | --- | --- |
| lat | 44.8378 | Latitude titik pencarian |
| lng | -0.5792 | Longitude titik pencarian |
| radius | 600 | Jangkauan yang diminta dalam meter |
| limit | 10 | Batas hasil yang diminta |
| modes | bus,tram | Moda yang dicari |

Koordinat ini adalah contoh pencarian di Bordeaux; ini bukan jaminan keberadaan henti. Lihat [kontrak OpenAPI ROOTE](https://api.roote.ai/openapi.json) untuk batasan, bidang, dan kondisi saat ini.

## Mengirim permintaan awal dari sisi server

Berikut contoh JavaScript untuk lingkungan Node.js dengan fetch. Token, jika akses Anda memerlukan, disimpan sebagai variabel lingkungan di sisi server. Contoh ini tidak memerlukan penempatan rahasia di peramban.

```
async function rechercherArrets(token = process.env.ROOTE_API_TOKEN) {
  const url = new URL('https://api.roote.ai/v1/transit/nearby');
  url.search = new URLSearchParams({
    lat: '44.8378',
    lng: '-0.5792',
    radius: '600',
    limit: '10',
    modes: 'bus,tram'
  }).toString();

  const headers = { Accept: 'application/json' };
  if (token) headers.Authorization = `Bearer ${token}`;

  const response = await fetch(url, {
    headers,
    signal: AbortSignal.timeout(10000)
  });
  if (!response.ok) {
    throw new Error(`Erreur HTTP ${response.status}`);
  }

  const data = await response.json();
  if (data.contract_version !== 'roote-1.0.0') {
    throw new Error('Version du contrat non reconnue');
  }
  if (!['success', 'empty', 'partial'].includes(data.status)) {
    throw new Error('Recherche indisponible');
  }
  if (!Array.isArray(data.stations)) {
    throw new Error('Réponse sans collection stations valide');
  }

  return {
    status: data.status,
    stations: data.stations,
    lines: data.lines,
    operators: data.operators,
    coverage: data.coverage,
    warnings: data.warnings,
    attributions: data.attributions,
    meta: data.meta
  };
}
```

Kontrak yang digunakan menyediakan akses anonim atau token, sesuai kebijakan yang berlaku. Periksa hak akses dan batas akses Anda. Respons HTTP yang benar tidak menggantikan validasi kontennya; dalam produksi, gunakan juga validasi objek berdasarkan skema.

## Membaca entitas dan relasinya

Koleksi stations berisi lokasi yang dikembalikan. Untuk setiap lokasi, periksa terutama id, name, entity_kind, location, dan distance_meters. Referensi line_ids dan operator_ids memungkinkan menghubungkan koleksi lines dan operators jika tersedia.

Tampilkan jarak geografis sebagaimana adanya. Jangan ubah menjadi waktu berjalan kaki tanpa kalkulasi rute. Panduan [menemukan henti terdekat](https://www.roote.ai/id/guides/cara-menemukan-titik-berhenti-bus-atau-tram-terdekat/) menjelaskan mengapa akses dapat memengaruhi perjalanan sebenarnya.

Tangani juga informasi tidak dikenal secara eksplisit. Dalam kontrak, accessibility.wheelchair bisa bernilai unknown: nilai ini bukan yes ataupun no. Kapasitas keberangkatan bukan merupakan daftar keberangkatan.

## Menampilkan daftar atau peta

Gunakan pengenal untuk menstabilkan elemen antarmuka, nama untuk label, dan lokasi untuk posisi. Gabungkan rute menggunakan referensi, bukan hanya membandingkan nama.

Jika Anda menampilkan warna rute atau label dari data, perlakukan sebagai entri eksternal yang harus divalidasi. Untuk nama, gunakan teks, bukan HTML yang disisipkan.

Pertahankan atribusi sumber dan tampilkan yang diwajibkan oleh kontrak.

## Menangani hasil kosong, respons parsial, dan kesalahan

Hasil empty menunjukkan pencarian tanpa hasil dalam cakupan yang diketahui. Ini tidak membuktikan ketiadaan fisik transportasi. Respons partial dapat berisi lokasi berguna sekaligus memberi batasan: tampilkan hasil dan peringatan yang sesuai.

Baca coverage, warnings, dan batasan dalam meta. Daftar yang terpotong bukan cakupan lengkap. Jika terjadi kesalahan jaringan atau HTTP, tampilkan ketidaktersediaan tanpa mengganti hasil dengan "tidak ada henti".

Untuk kode 429, lihat petunjuk pemulihan dan header layanan yang mungkin ada. Hindari pengulangan otomatis.

## Membedakan stasiun, zona, dan peron

Kolom entity_kind membedakan beberapa tingkat lokasi. Dua hasil berdekatan mungkin adalah peron berbeda; dua nama mirip bisa berasal dari sumber berbeda.

Jangan gabungkan lokasi hanya berdasarkan kedekatan. Gunakan relasi dan identitas yang didokumentasikan oleh layanan. Panduan kami [GTFS, GTFS-RT dan GBFS](https://www.roote.ai/id/guides/gtfs-gtfs-rt-dan-gbfs-apa-perbedaannya/) menjelaskan konteks datanya.

## Mempersiapkan integrasi ke produksi

Mulai pencarian saat posisi atau filter berubah secara bermakna. Gabungkan panggilan berulang, tetapkan waktu tunggu, dan sesuaikan cache dengan jenis data dan kondisi layanan.

Daftar lokasi dan data waktu nyata memiliki kebutuhan kesegaran berbeda. Uji alur dengan respons lengkap, kosong, parsial, dan kesalahan sebelum menampilkan pencarian pada pengguna.

## Perluas pencarian ke layanan perkotaan

Titik henti dan layanan perkotaan menggunakan rute yang berbeda. Untuk mencari toilet di sekitar titik yang sama, rute GET /v1/services/nearby membutuhkan lat dan lon, dengan types=toilets. Jangan kirim modes=toilets ke rute ini: kosakata itu milik URL peta, bukan filter Layanan.

Contoh JavaScript berikut membangun URL Layanan untuk radius 600 meter. Ini tidak memicu permintaan; gunakan ulang kontrol HTTP dan kontrak yang dijelaskan sebelumnya. Koleksi yang diharapkan menjadi services, bukan stations. Simpan service_type, location, distance_meters dan atribut yang benar-benar ada.

Kontrak REST mendokumentasikan antara lain toilets, drinking_water, fountain, wifi, parking, charging, aed dan locker. Jenis yang ditampilkan oleh MCP bisa berbeda. Untuk parameter yang diterima, batasnya dan limit akses Anda, lihat skema antarmuka yang digunakan.

Atribut sebuah layanan tidak menjamin layanan tersebut buka saat pencarian dilakukan. Aksesibilitas yang tidak diketahui tidak sama dengan layanan tidak dapat diakses; daftar kosong karena kesalahan tidak membuktikan tidak adanya toilet. Simpan data sesuai masing-masing keluarga daripada hanya mereduksinya menjadi nama dan titik.

Untuk peta gabungan, hubungkan hasil dengan keluarganya dan identifikatornya. Tampilkan kesalahan Layanan tanpa menghapus titik henti yang dikembalikan oleh Transit. Pencarian tetap terpusat pada titik yang sama, tetapi status dan cakupan bisa berbeda.

```
const url = new URL('https://api.roote.ai/v1/services/nearby');
url.search = new URLSearchParams({
  lat: '44.8416106', lon: '-0.5810938',
  radius: '600', limit: '10', types: 'toilets'
}).toString();
console.log(url.toString());
```

[Mendiagnosis pencarian kosong atau kesalahan](https://www.roote.ai/id/guides/hasil-kosong-atau-error-api-bagaimana-membedakannya/)

[Mengintegrasikan peta terfilter langsung ke dalam situs](https://www.roote.ai/id/guides/cara-mengintegrasikan-peta-mobilitas-di-situs-anda/)

[Membangun asisten di sekitar pencarian ini](https://www.roote.ai/id/guides/cara-membuat-asisten-mobilitas-di-sekitar-alamat/)

## Pertanyaan yang sering diajukan

### Apakah Nearby menyediakan keberangkatan berikutnya?

Tidak dalam kontrak yang ditunjukkan di sini. Rute ini hanya menemukan lokasi transportasi; keberangkatan memerlukan kapabilitas terpisah.

### Bisakah menampilkan daftar kosong setelah kesalahan?

Tampilkan ketidaktersediaan. Kesalahan tidak membuktikan ketiadaan henti.

### Bisakah menempatkan token API di peramban?

Rahasia harus tetap di sisi server. Gunakan model akses yang disediakan untuk aplikasi dan akun Anda.
