Basic Consume API
Proses consume API adalah langkah-langkah yang dilakukan oleh aplikasi atau sistem untuk mengakses dan menggunakan data atau layanan yang disediakan oleh API.
Tutorial Consume API
Prasyarat
Sebelum memulai, pastikan komputer Anda sudah siap dengan:
- Node.js (Versi 22 atau lebih baru disarankan).
- MongoDB (Pastikan MongoDB Service sudah berjalan di latar belakang).
- Git (Untuk meng-clone repository).
Persiapan Backend: Menyiapkan Movie API untuk Praktek Consume Data
Jika kamu belum punya project backend nya atau error silahkan ikutin langkah ini atau jika sudah punya silahkan di skip
Langkah 1: Clone backend
Langkah pertama adalah mengambil kode proyek API yang sudah disiapkan. Kita akan menggunakan perintah git clone. Buka terminal atau command prompt kamu, lalu jalankan:
git clone https://github.com/StayLearnCode/movie-express.gitLangkah 2: Instalasi Dependencies
Setelah berhasil di-clone, kita perlu masuk ke folder proyek tersebut dan menginstal paket-paket yang diperlukan agar kode bisa berjalan.
cd movie-express
npm installLangkah 3: Mengisi Data Awal (Database Seeding)
Kita perlu melakukan Seeding. Seeding adalah proses mengisi database dengan data awal/contoh secara otomatis.
Jalankan perintah berikut secara berurutan:
cd seeders
node index.jsLangkah 4: Menjalankan Server
Sekarang datanya sudah ada, saatnya menyalakan server!
Pertama, kita harus keluar dulu dari folder seeders untuk kembali ke folder utama, lalu jalankan servernya.
cd ..
npm run devPersiapan Frontend: Mengintegrasikan Axios pada React
Sebelum kita mulai menulis kode untuk mengambil data, pastikan kamu telah membuka kembali project React yang kita gunakan pada materi Basic React Router. Kita akan melanjutkan pengembangan.
Mengapa Kita Menggunakan Axios?
Untuk mengambil data dari API, JavaScript sebenarnya menyediakan fitur standar browser yang disebut Fetch API. Kita bisa menggunakannya tanpa perlu menginstal apa pun.
Namun, dalam pengembangan aplikasi skala produksi, Fetch API memiliki beberapa keterbatasan teknis yang membuatnya kurang efisien untuk digunakan secara langsung:
- Penanganan JSON Manual: Anda harus melakukan parsing data JSON secara manual di setiap request.
- Penanganan Error Terbatas: Fetch tidak menganggap status HTTP 404 atau 500 sebagai error secara default, sehingga memerlukan logika tambahan untuk menanganinya.
- Kode Berulang (Boilerplate): Memerlukan lebih banyak baris kode untuk pengaturan header dan konfigurasi request.
Oleh karena itu, kita akan menggunakan Axios. Axios adalah library HTTP Client yang mengatasi masalah teknis di atas. Ia menangani parsing JSON secara otomatis, memiliki penanganan error yang lebih baik, dan membuat sintaks kode kita menjadi lebih ringkas dan mudah dibaca.
Langkah 1: Instalasi Library Axios
Karena Axios adalah library eksternal, kita perlu menambahkannya ke dalam project kita terlebih dahulu. Buka terminal kamu dan pastikan kamu berada di dalam folder project React, lalu jalankan perintah berikut:
npm install axiosLangkah 2: Menjalankan Project
Setelah instalasi selesai, mari kita pastikan tidak ada error yang terjadi akibat penambahan library baru tersebut. Jalankan server pengembangan dengan perintah:
npm run devJika server berjalan tanpa pesan error di terminal, berarti Axios telah berhasil terinstal dan project kamu siap untuk tahap selanjutnya.
Langkah 3: Membuat utils atau helpers untuk Axios
Dalam pengembangan aplikasi yang skalabel, menulis URL API lengkap (misalnya http://localhost:3000/api/movies) secara berulang di setiap komponen adalah praktik yang tidak efisien. Jika alamat server berubah, Anda harus mengubahnya di banyak tempat.
Solusinya adalah membuat satu instance Axios yang dikonfigurasi secara terpusat. Kita akan menempatkan konfigurasi ini dalam folder utils (utilities) atau helpers.
Silakan buat folder baru bernama utils di dalam direktori src, kemudian buat file baru bernama ApiClient.ts.
Selanjutnya, salin kode berikut ke dalam file ApiClient.ts:
import axios from "axios"
const ApiClient = axios.create({
baseURL : "http://localhost:3000/api",
headers : {
"Content-Type": "application/json",
}
})
export default ApiClient;Penjelasan Kode:
axios.create({...}): Fungsi ini membuat instance baru dari Axios. Instance ini adalah versi Axios yang telah kita sesuaikan pengaturan standarnya.baseURL: Kita menetapkan alamat dasar API. Nantinya, saat memanggil endpoint (misalnya /movies), Axios akan otomatis menggabungkannya menjadihttp://localhost:3000/api/movies. Ini membuat kode di komponen lain menjadi lebih bersih.headers: Kita menetapkan standar header Content-Type: application/json untuk memastikan server tahu bahwa data yang kita kirim atau minta berformat JSON.export default: Kita mengekspor konfigurasi ini agar bisa diimpor dan digunakan di seluruh bagian aplikasi.
Consume API
Sekarang setelah konfigurasi Axios (ApiClient) siap, kita akan masuk pada tahap menghubungkan halaman frontend dengan data dari backend.
Mengimplementasikan Fitur Read (Fetch Data)
Langkah-langkah Update Component Movies
Silakan buka file src/pages/Movies.tsx. Kita akan melakukan perubahan signifikan pada file ini untuk menangani tiga kondisi utama dalam pengambilan data:
- Loading: Saat data sedang diambil.
- Success: Saat data berhasil diambil.
- Error: Saat terjadi kegagalan (misalnya server mati).
Copas kode berikut untuk menggantikan isi file Movies.tsx Kamu:
import { NavLink } from "react-router";
import { useCallback, useEffect, useState } from "react";
import ApiClient from "../utils/ApiClient"; // Pastikan path import sesuai dengan struktur folder Anda
import { Table } from "react-bootstrap";
// 1. Definisi Tipe Data
interface Movie {
_id: string;
judul: string;
tahunRilis: string;
sutradara: string;
createdAt: string;
updatedAt: string;
}
function Movies() {
// 2. State Management
const [movies, setMovies] = useState<Movie[]>([]);
const [loading, setLoading] = useState<boolean>(true);
const [error, setError] = useState<string | null>(null);
// 3. Fungsi Pengambilan Data
const fetchMovies = useCallback(async () => {
setLoading(true); // Mulai status loading
setError(null); // Reset error sebelum mencoba request baru
try {
const response = await ApiClient.get("/movies");
if (response.status === 200) {
setMovies(response.data.data);
}
} catch (error) {
console.error("Error fetching data:", error);
setError("Gagal mengambil data dari server.");
} finally {
setLoading(false); // Hentikan status loading apapun hasilnya
}
}, []);
// 4. Lifecycle Hook
useEffect(() => {
fetchMovies();
}, [fetchMovies]);
return (
<div className="container mx-auto py-3">
<div className="d-flex justify-content-between mb-3">
<h4>Daftar Film</h4>
<NavLink to="/add-movie" className="btn btn-primary">
Tambah Film
</NavLink>
</div>
{/* 5. Conditional Rendering */}
<div>
<Table striped bordered hover size="sm">
<thead>
<tr>
<th>No</th>
<th>Judul</th>
<th>Tahun Rilis</th>
<th>Sutradara</th>
</tr>
</thead>
<tbody>
{/* Kondisi 1: Sedang Memuat */}
{loading && (
<tr>
<td colSpan={4} className="text-center">Sedang memuat data...</td>
</tr>
)}
{/* Kondisi 2: Terjadi Error */}
{error && (
<tr>
<td colSpan={4} className="text-center text-danger">{error}</td>
</tr>
)}
{/* Kondisi 3: Data Kosong */}
{!loading && !error && movies.length === 0 && (
<tr>
<td colSpan={4} className="text-center">Tidak ada data film tersedia.</td>
</tr>
)}
{/* Kondisi 4: Data Berhasil Dimuat */}
{!loading && !error && movies.length > 0 && movies.map((movie, index) => (
<tr key={movie._id}>
<td>{index + 1}</td>
<td>{movie.judul}</td>
<td>{movie.tahunRilis}</td>
<td>{movie.sutradara}</td>
</tr>
))}
</tbody>
</Table>
</div>
</div>
);
}
export default Movies;Penjelasan Kode
1. TypeScript Interface (interface Movie)
Kita mendefinisikan struktur data Movie. Ini membantu TypeScript memvalidasi bahwa data yang kita terima dari API dan data yang kita tampilkan di tabel memiliki struktur yang konsisten, sehingga mencegah error properti undefined.
2. State Management (useState)
Kita menggunakan tiga state terpisah untuk mengontrol UI:
movies: Array untuk menyimpan data film yang berhasil diambil.loading: Boolean (true/false) untuk menentukan apakah indikator loading harus muncul. Defaultnyatrueagar loading muncul saat halaman pertama kali dibuka.error: String untuk menyimpan pesan kesalahan jika request gagal.
3. fetchMovies dengan useCallback
Fungsi ini bertugas memanggil API.
ApiClient.get("/movies"): Kita hanya menulis/movieskarenabaseURLsudah diatur diApiClient.ts.try...catch...finally: Blok ini penting untuk menangani alur request. Jika sukses, data disimpan. Jika gagal, error dicatat. Blokfinallymemastikan statusloadingdimatikan, baik request itu sukses maupun gagal.useCallback: Kita membungkus fungsi ini agar referensi memorinya tidak berubah setiap kali komponen di-render ulang, mencegah infinite loop padauseEffect.
4. useEffect Hook
Hook ini berfungsi sebagai pemicu. Dengan array dependency [fetchMovies], React akan menjalankan fungsi fetchMovies segera setelah komponen Movies di-mount (ditampilkan) ke layar.
5. Conditional Rendering
Di dalam bagian return (JSX), kita tidak sekadar menampilkan tabel. Kita menangani pengalaman pengguna (User Experience) dengan logika:
- Jika
loadingtrue -> Tampilkan teks "Sedang memuat...". - Jika
errorada -> Tampilkan pesan error merah. - Jika data kosong -> Beritahu user bahwa belum ada data.
- Jika semua lancar -> Lakukan mapping data
movieske dalam baris tabel (<tr>).