JavaRush /Курсы /Модуль 3: React /Типизация запросов и ответов с Axios и интерфейсы TypeScr...

Типизация запросов и ответов с Axios и интерфейсы TypeScript

Модуль 3: React
11 уровень , 6 лекция
Открыта

Интерфейсы для запросов и ответов

Для работы с TypeScript мы будем использовать интерфейсы — любимый инструмент для описания формата наших данных.

Пример интерфейса

Предположим, у нас есть API, которое получает список пользователей. Оно возвращает массив объектов с информацией о пользователях: ID, имя и email. Вот как мы можем описать эти данные:

// Описание структуры данных, возвращаемых API
interface User {
  id: number;
  name: string;
  email: string;
}

Если вы когда-либо работали с JSON, то интерфейсы — это просто его "тип". Зная структуру данных, которые вы ожидаете, вы можете заранее описать их формат.

Типизация данных при использовании Axios

Когда мы делаем запросы с Axios, мы можем явно указать, какого типа ответ мы ожидаем. Это особенно полезно, если API возвращает сложные структуры.

Основной синтаксис типизации Axios

Axios предоставляет возможность определить тип ответа, используя параметр <T>.

Вот как это работает:

import axios from 'axios';

// Типизируем наши данные
interface User {
  id: number;
  name: string;
  email: string;
}

// Делаем запрос и типизируем ответ
axios.get<User[]>('https://jsonplaceholder.typicode.com/users')
  .then(response => {
    // Теперь TypeScript знает, что response.data — это массив объектов User
    const users = response.data;
    console.log(users[0].name); // Всё ок — TypeScript подскажет, что name есть у User
  })
  .catch(error => {
    console.error('Ошибка при запросе:', error);
  });

В данном примере:

  • User[] говорит, что ответ будет массивом объектов типа User.
  • TypeScript будет ругаться, если вы попробуете получить, например, users[0].age (ведь мы не указали, что у User есть поле age).

Подключение типов к конфигурации запросов

Иногда запросы требуют дополнительных данных: параметров, заголовков или тела. Хорошая новость: мы тоже можем их типизировать.

Предположим, вы хотите добавить нового пользователя через API. Для этого вам нужно отправить POST-запрос с телом, содержащим данные пользователя. Мы можем заранее типизировать это тело:

interface NewUser {
  name: string;
  email: string;
  password: string;
}

// Типизируем тело запроса
const newUser: NewUser = {
  name: 'Иван Иванов',
  email: 'ivan@example.com',
  password: 'password123'
};

// Отправляем запрос
axios.post<User>('https://jsonplaceholder.typicode.com/users', newUser)
  .then(response => {
    // Ответ автоматически типизируется как User
    console.log('Создан пользователь:', response.data);
  })
  .catch(error => {
    console.error('Ошибка при создании пользователя:', error);
  });

Преимущества точной типизации в Axios

Теперь, когда мы типизируем запросы, возникает вопрос: а что если ответ не соответствует ожидаемой структуре?

Встроенная защита от ошибок

TypeScript помогает нам избежать таких проблем ещё на этапе разработки. Например, если вы добавите поле, которого нет в интерфейсе, TypeScript сразу даст вам знать.

// Ошибка! Поле "age" не определено в интерфейсе NewUser
const invalidUser: NewUser = {
  name: 'Иван',
  email: 'ivan@example.com',
  password: '123456',
  age: 30 // <- TypeScript скажет: "Эй, этого поля нет!"
};

Продвинутый пример: обработка ответа с дополнительной метаинформацией

Иногда сервер возвращает не только данные, но и дополнительную информацию, такую как общее количество записей, пагинация и т.д. Как типизировать такие ответы?

Пример с пагинацией

Допустим, наш API возвращает такой ответ:

{
  "data": [
    { "id": 1, "name": "Иван Иванов", "email": "ivan@example.com" },
    { "id": 2, "name": "Мария Петрова", "email": "maria@example.com" }
  ],
  "total": 50,
  "page": 1,
  "pageSize": 10
}

Мы можем описать тип такого ответа следующим образом:

interface PaginationResponse<T> {
  data: T[];
  total: number;
  page: number;
  pageSize: number;
}

// Типизируем данные пользователей
interface User {
  id: number;
  name: string;
  email: string;
}

// Типизируем ответ API
axios.get<PaginationResponse<User>>('https://jsonplaceholder.typicode.com/users')
  .then(response => {
    const { data, total, page, pageSize } = response.data;
    console.log(`Получено ${data.length} пользователей из ${total}`);
  })
  .catch(error => {
    console.error('Ошибка при запросе:', error);
  });

Теперь можно легко переиспользовать PaginationResponse для других типов данных, не только User.

Типизация ошибок

Типизация полезна не только для успешных запросов, но и для обработки ошибок.

Axios позволяет вам перехватывать ошибки и обрабатывать их централизованно:

interface ApiError {
  message: string;
  statusCode: number;
}

axios.get<User[]>('https://jsonplaceholder.typicode.com/404')
  .then(response => {
    console.log('Успешный ответ:', response.data);
  })
  .catch((error: Axios.AxiosError<ApiError>) => {
    if (error.response) {
      console.error(`Ошибка API: ${error.response.data.message}`);
    } else {
      console.error('Неизвестная ошибка:', error.message);
    }
  });

Реальный пример: создание API-сервиса

Часто бывает удобно вынести всю логику работы с API в отдельный модуль. Давайте создадим простой API-сервис для работы с пользователями.

import axios from 'axios';

interface User {
  id: number;
  name: string;
  email: string;
}

const api = axios.create({
  baseURL: 'https://jsonplaceholder.typicode.com'
});

export const getUsers = async (): Promise<User[]> => {
  const response = await api.get<User[]>('/users');
  return response.data;
};

export const createUser = async (user: Omit<User, 'id'>): Promise<User> => {
  const response = await api.post<User>('/users', user);
  return response.data;
};

// Пример использования
getUsers().then(users => console.log(users));
createUser({ name: 'Иван', email: 'ivan@example.com' }).then(user => console.log(user));

Вот так мы создали удобный сервис с функциями getUsers и createUser. Его можно легко использовать в любом компоненте React.

TypeScript и Axios — действительно мощная комбинация, которая позволяет разработчикам писать более безопасный и читаемый код. Теперь запросы к API становятся гораздо менее пугающими!

1
Задача
Модуль 3: React, 11 уровень, 6 лекция
Недоступна
Отправка типизированных данных с помощью Axios
Отправка типизированных данных с помощью Axios
1
Задача
Модуль 3: React, 11 уровень, 6 лекция
Недоступна
Типизация данных с пагинацией
Типизация данных с пагинацией
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ