Введення в Axios та TypeScript
- Що таке Axios і чому його використовувати?
Axios — це обіцяно-орієнтований HTTP клієнт для node.js
та браузера. Він є ізоморфним (= може працювати як у браузері, так і в nodejs, використовуючи однакову базу коду). На сервері він використовує рідний модуль http
з node.js, а на клієнті (у браузері) — XMLHttpRequests.
Чому використовувати Axios?
- Axios абстрагує складні функції API fetch(), спрощуючи HTTP запити.
- Він підтримує автоматичне перетворення JSON за заголовком Content-Type та дозволяє кастомізувати парсинг відповіді через transformResponse.
- Axios працює в усіх сучасних браузерах (Chrome, Firefox, Safari, Edge, Opera) і підтримує Internet Explorer 11 з поліфілами.
Переваги використання TypeScript разом з Axios
- Спрощений синтаксис: використання методів .get() та .post() для чистішого коду.
- Безпека типів: TypeScript допомагає визначити очікувані типи відповідей, роблячи ваш код більш надійним щодо помилок під час виконання.
Налаштування Axios у проекті TypeScript
Щоб інтегрувати Axios у ваш проект, виконайте наступні команди в терміналі
npm install axios
npm install --save-dev @types/axios
- Налаштування Axios у TypeScript
Ось як ви можете встановити деякі значення за замовчуванням для Axios:
import axios from 'axios';
axios.defaults.baseURL = 'https://api.example.com';
axios.defaults.headers.common['Authorization'] = 'Bearer your-token';
axios.defaults.timeout = 5000; // тайм-аут 5 секунд
Ви можете використовувати файл .env для специфічних для середовища налаштувань.
Основний GET запит з Axios
Ось приклад простого GET запиту:
export const fetchData = async () => {
const response = await axios.get('https://api.open-meteo.com/v1/forecast?latitude=54.9046&longitude=-1.3822¤t=apparent_temperature&models=ukmo_seamless');
return response.data;
};
Примітка: Цей приклад не включає анотацій типів для даних відповіді.
Визначення типів відповідей з TypeScript
Використання інтерфейсів TypeScript для даних відповіді
interface User {
id: number;
name: string;
role: string;
}
// Додавання безпеки типів для відповіді
axios.get('https://api.example.com/users', {
params: { id: 123 },
})
.then(response => {
const user: User = response.data;
console.log(user.name); // Доступ до типізованої властивості
});
Цей підхід забезпечує безпеку типів у вашому коді, але що, якщо API не поверне те, що ви очікуєте?
Обробка помилок з Axios у TypeScript
Об'єкти помилок Axios надають:
- error.response: Відповідь сервера, якщо вона доступна.
- error.request: Запит, який не отримав відповіді.
- error.message: Описова помилка.
- error.config: Конфігурація Axios для запиту.
Обробка помилок з Axios
Ось як обробити помилки:
axios.get('https://api.example.com/invalid-endpoint')
.then(response => {
console.log('Data:', response.data);
})
.catch(error => {
if (error.response) {
// Сервер відповів статусом, що виходить за межі діапазону 2xx
console.error('Error Status:', error.response.status);
console.error('Error Data:', error.response.data);
} else if (error.request) {
// Запит було надіслано, але не отримано відповідь
console.error('No Response Received:', error.request);
} else {
// Щось пішло не так при налаштуванні запиту
console.error('Request Error:', error.message);
}
});
Для більш специфічної обробки помилок:
axios.get('https://api.example.com/data', { timeout: 5000 })
.then(response => {
console.log('Data:', response.data);
})
.catch(error => {
if (error.code === 'ECONNABORTED') {
console.error('Request Timed Out');
} else {
console.error('Network Error:', error.message);
}
});
В асинхронних функціях:
async function fetchData() {
try {
const response = await axios.get('https://api.example.com/data');
console.log('Data:', response.data);
} catch (error) {
if (error.response) {
console.error('Error Status:', error.response.status);
console.error('Error Data:', error.response.data);
} else if (error.request) {
console.error('No Response Received:', error.request);
} else {
console.error('Request Error:', error.message);
}
}
}
Ми можемо націлюватися на статуси запитів:
axios.interceptors.response.use(
response => response, // Пропускаємо, якщо відповідь успішна
error => {
if (error.response?.status === 401) {
console.error('Unauthorized (401): Please log in.');
} else if (error.response?.status === 500) {
console.error('Server error (500): Try again later.');
} else {
console.error('An error occurred:', error.message);
}
return Promise.reject(error); // Продовжуємо помилку
}
);
Іноді вам може знадобитися повторити той самий запит, якщо він не вдався з першого разу. В такому випадку потрібно встановити axios-retry, і це спробує виконати кожен виклик axios стільки разів, скільки ви вкажете.
Використання Retry з Axios
3 рази у наведеному прикладі.
import axiosRetry from 'axios-retry';
import axios from 'axios';
// Налаштування повторних спроб для Axios
axiosRetry(axios, { retries: 3 });
axios.get('https://api.example.com/data')
.then(response => {
console.log('Data:', response.data);
})
.catch(error => {
console.error('Failed after retries:', error.message);
});
Якщо потрібно обробити помилку axios у TypeScript, можна використовувати тип AxiosError для безпечного доступу до властивостей у блоці catch.
import axios, { AxiosError } from 'axios';
axios.get('https://api.example.com/data')
.then(response => console.log(response.data))
.catch((error: AxiosError) => {
if (error.response) {
console.error('Error Status:', error.response.status);
console.error('Error Data:', error.response.data);
} else if (error.request) {
console.error('No Response Received:', error.request);
} else {
console.error('Request Error:', error.message);
}
});
Робота з параметрами URL та рядками запиту
- Додавання параметрів запиту у GET-запити Axios
Якщо нам потрібен певний рядок з бази даних, ми можемо передати індекс через параметр, тут ми передаємо key1 та key2 як параметри. Axios додасть їх до URL.
import axios from 'axios';
axios.get('https://api.example.com/data', {
params: {
key1: 'value1',
key2: 'value2',
},
})
.then(response => {
console.log('Response Data:', response.data);
})
.catch(error => {
console.error('Error:', error);
});
Нижче ви можете побачити HTML-кодування обох параметрів за допомогою вказаних імен властивостей об'єкта та значень, які вони містять.
https://api.example.com/data?key1=value1&key2=value2
- Типізація параметрів запиту для підвищення безпеки типів
Нижче ми передаємо об'єкт у нашу функцію отримання даних. Ця функція очікує, що об'єкт міститиме властивості, які вказані в описі нашого інтерфейсу. Це захищає наш виклик до API, гарантуючи, що наші дані мають очікувані типи.
import axios from 'axios';
interface QueryParams {
q: string;
page: number;
sort?: string; // Необов'язковий параметр
}
async function fetchData(params: QueryParams): Promise {
try {
const response = await axios.get('https://api.example.com/search', { params });
console.log('Results:', response.data);
} catch (error) {
console.error('Error:', error);
}
}
fetchData({ q: 'typescript', page: 1, sort: 'asc' });
Ось як axios обробить ці параметри.
https://api.example.com/search?q=typescript&page=1&sort=asc
Скасування запитів з Axios у TypeScript
В нових версіях axios ми можемо використовувати AbortController для скасування запиту, прикріплюючи сигнал до даних. Потім ми можемо викликати controller.abort, щоб скасувати запит. Це може бути корисно, коли користувач хоче скасувати запит, щоб виконати іншу дію.
import axios from 'axios';
const controller = new AbortController(); // Створення AbortController
async function fetchData() {
try {
const response = await axios.get('https://api.example.com/data', {
signal: controller.signal, // Прикріплення сигналу AbortController
});
console.log('Response:', response.data);
} catch (error) {
if (error.name === 'CanceledError') {
console.error('Request canceled:', error.message);
} else {
console.error('Error:', error);
}
}
}
// Початок запиту
fetchData();
// Скасування запиту
controller.abort(); // Скасовує запит
Аутентифікація та авторизація в запитах Axios
- Надсилання токенів аутентифікації з GET-запитами в Axios
Зараз у API є багато різних заголовків, які ми можемо додавати. Один з них — заголовок Authorization
. Це найчастіше використовується для токенів, але існує багато способів здійснити Authorization
, що залежить від того, яке API ви використовуєте. Ось приклад з Authorization
.
Використання токенів Bearer з Axios
Ви помітите, що ми додаємо токен з префіксом Bearer
, але це залежить від API. Нижче ми додали об'єкт headers і помістили це всередину.
const token = 'your-token-here';
axios.post('https://api.example.com/protected-resource',
{ data: 'exampleData' }, // Тіло запиту
{
headers: {
Authorization: `Bearer ${token}`, // Додаємо токен
},
}
)
.then(response => {
console.log('Response:', response.data);
})
.catch(error => {
console.error('Error:', error);
});
- Обробка токенів Bearer з Axios та TypeScript
У TypeScript ви можете зробити виклик, розширивши authHeaders, щоб включити рядок авторизації. Потім ви можете додати це до запиту.
import axios, { AxiosRequestConfig } from 'axios';
// Визначення типу заголовка токена
interface AuthHeaders extends AxiosRequestConfig {
headers: {
Authorization: string;
};
}
const token = 'your-token-here';
const config: AuthHeaders = {
headers: {
Authorization: `Bearer ${token}`,
},
};
axios.get('https://api.example.com/protected-resource', config)
.then(response => {
console.log('Response:', response.data);
})
.catch(error => {
console.error('Error:', error);
});
Ви навіть можете використовувати інтерсептори (interceptors), щоб автоматично додавати токен щоразу, коли ви робите запит, якщо це необхідно, передаючи токен через localStorage, коли користувач виконує дію.
Типові проблеми та налагодження Axios у TypeScript
- Проблеми з CORS: Перевірте вкладку мережі в інструментах розробника браузера на наявність проблем з Access-Control-Allow-Origin.
- Перевірте підтримку методів сервером: Переконайтеся, що сервер підтримує HTTP методи, заголовки та джерело (origin), які ви використовуєте.
Налагодження помилок Axios у TypeScript-додатках
- Використовуйте axios.isAxiosError() для перевірки помилок, специфічних для Axios.
- Логуйте запити та відповіді за допомогою інтерсепторів (interceptors) для детального налагодження.
Кращі практики
- Використовуйте змінні середовища для API-ключів і чутливих даних.
- Реалізуйте належне оброблення помилок та логування для продакшн-оточення.
- Використовуйте узагальнення (generics) TypeScript з Axios для ще більш суворої перевірки типів.
Додаткові ресурси
Перекладено з: Your First API Call: GET Requests in Typescript using Axios