axios.get() menerima URL request dan satu configuration object opsional. Query parameter dan HTTP header bukan argumen posisi yang terpisah; keduanya merupakan properti dari configuration object tersebut.

Batas ini penting karena kode yang memperlakukan params dan headers sebagai dua config argument terpisah dapat menjadi JavaScript yang tidak valid atau menaruh konfigurasi di posisi yang tidak dibaca Axios.

Method GET memiliki satu batas config

Bentuk pemanggilannya adalah:

axios.get(url, config)

Request configuration dapat memuat beberapa kebutuhan sekaligus:

axios.get('/merchants', {
  params: {
    search: searchTerm,
    sort: `${sortField}.${sortDirection}`,
  },
  headers: {
    Authorization: `Bearer ${token}`,
  },
});

params mengatur serialisasi query string. headers mengatur request header. Keduanya berada di dalam configuration object yang sama.

Pada lapisan HTTP, request tersebut dapat berbentuk:

GET /merchants?search=acme&sort=name.asc
Authorization: Bearer <token>

Query string dan header berada pada bagian HTTP yang berbeda, tetapi Axios menerima konfigurasi per-request keduanya melalui satu object JavaScript.

Object anonim di dalam object lain bukan sintaks yang valid

Kesalahan yang umum terjadi adalah menulis object literal kedua di dalam config object tanpa memberinya properti:

axios.get('/merchants', {
  params: {
    search: searchTerm,
  },
  {
    headers: {
      Authorization: `Bearer ${token}`,
    },
  },
});

Brace terluar sudah membentuk sebuah object literal. Setelah params, JavaScript mengharapkan definisi properti berikutnya. Object literal yang berdiri sendiri bukan entri properti yang valid pada posisi tersebut.

Perbaikannya bersifat struktural:

axios.get('/merchants', {
  params: {
    search: searchTerm,
  },
  headers: {
    Authorization: `Bearer ${token}`,
  },
});

params dan headers menjadi properti sejajar dari satu object.

Argumen ketiga bukan config Axios kedua

JavaScript mengizinkan function dipanggil dengan argumen lebih banyak daripada yang digunakan function tersebut. Karena itu, variasi berikut dapat terlihat valid:

axios.get(
  '/merchants',
  {
    params: {
      search: searchTerm,
    },
  },
  {
    headers: {
      Authorization: `Bearer ${token}`,
    },
  },
);

Kode ini valid secara sintaks JavaScript, tetapi tidak sesuai dengan bentuk API GET Axios. Request alias GET menerima URL diikuti satu config object opsional. Object ketiga bukan request config kedua.

Semua opsi per-request harus tetap berada di argumen kedua:

axios.get('/merchants', {
  params: {
    search: searchTerm,
  },
  headers: {
    Authorization: `Bearer ${token}`,
  },
});

Opsi request lain menggunakan object yang sama

Aturan yang sama berlaku ketika request juga membutuhkan timeout atau cancellation:

const controller = new AbortController();

axios.get('/merchants', {
  params: {
    search: searchTerm,
    sort: `${sortField}.${sortDirection}`,
  },
  headers: {
    Authorization: `Bearer ${token}`,
  },
  timeout: 5000,
  signal: controller.signal,
});

params, headers, timeout, dan signal semuanya merupakan properti request config. Menambahkan opsi request tidak berarti menambahkan config argument baru.

Konfigurasi juga dapat disusun sebelum request dikirim:

const config = {
  params: {
    search: searchTerm,
    sort: `${sortField}.${sortDirection}`,
  },
  headers: {
    Authorization: `Bearer ${token}`,
  },
};

const response = await axios.get('/merchants', config);

Config object yang diberi nama berguna ketika kode perlu menambahkan atau memeriksa opsi sebelum mengirim request.

Promise chain tidak mengubah request configuration

Baik response ditangani dengan .then() maupun async/await, signature pemanggilan Axios tetap sama.

Promise chain dapat menyimpan seluruh request configuration pada satu tempat:

loadingData = true;

axios.get(`${PUBLIC_API_BASE_URL}/merchants`, {
  params: {
    search: searchTerm,
    sort: `${sortField}.${sortDirection}`,
  },
  headers: {
    Authorization: `Bearer ${token}`,
  },
})
  .then((response) => {
    data = response.data.data;
  })
  .catch((error) => {
    console.error('Failed to fetch merchants:', error);
    toast.error('Failed to fetch merchants');
  })
  .finally(() => {
    loadingData = false;
  });

Bentuk async/await menggunakan request config yang sama:

async function fetchMerchants() {
  loadingData = true;

  try {
    const response = await axios.get(
      `${PUBLIC_API_BASE_URL}/merchants`,
      {
        params: {
          search: searchTerm,
          sort: `${sortField}.${sortDirection}`,
        },
        headers: {
          Authorization: `Bearer ${token}`,
        },
      },
    );

    data = response.data.data;
  } catch (error) {
    console.error('Failed to fetch merchants:', error);
    toast.error('Failed to fetch merchants');
  } finally {
    loadingData = false;
  }
}

Pilihan control-flow memengaruhi keterbacaan, bukan posisi params atau headers.

Autentikasi bersama dapat dipindahkan dari setiap call

Jika banyak request memakai bearer token yang sama, mengulang header pada setiap call menambah duplikasi. Axios instance dan request interceptor dapat memusatkan autentikasi bersama.

const api = axios.create({
  baseURL: PUBLIC_API_BASE_URL,
});

api.interceptors.request.use((config) => {
  const token = getAccessToken();

  if (token) {
    config.headers.Authorization = `Bearer ${token}`;
  }

  return config;
});

Request individual kemudian hanya membawa opsi yang spesifik untuk request tersebut:

const response = await api.get('/merchants', {
  params: {
    search: searchTerm,
    sort: `${sortField}.${sortDirection}`,
  },
});

Batas dasarnya tidak berubah. Axios tetap membentuk satu konfigurasi request efektif dari defaults, interceptor, dan per-request config object.

Perlakukan config object sebagai control surface request

Model ringkasnya:

axios.get(
  URL,
  {
    params,
    headers,
    timeout,
    signal,
    ...other request options
  }
)

Konsep HTTP yang direpresentasikan tetap berbeda, tetapi API Axios mengelompokkan konfigurasi per-request di dalam satu object.

Ketika GET request membutuhkan query parameter dan authorization sekaligus, menambahkan config object lain adalah abstraksi yang keliru. Letakkan params dan headers berdampingan di dalam satu config argument setelah URL.