Какие способы взаимодействия с серверным API ты используешь в Flutter?

«Какие способы взаимодействия с серверным API ты используешь в Flutter?» — вопрос из категории Сети, который задают на 29% собеседований Flutter Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Для работы с API в Flutter я обычно выстраиваю клиент-серверное взаимодействие по следующей схеме, используя несколько ключевых пакетов.

1. HTTP-клиент: Dio или http.

  • dio — мой основной выбор для сложных проектов. Он предоставляет перехватчики (interceptors) для логирования, добавления заголовков, обработки ошибок, поддержку отмены запросов (CancelToken) и встроенный парсинг JSON.

    final dio = Dio(BaseOptions(baseUrl: 'https://api.example.com'));
    dio.interceptors.add(LogInterceptor()); // Логирование
    
    // Запрос с обработкой ошибок
    try {
      Response response = await dio.get('/users/1');
      User user = User.fromJson(response.data);
    } on DioException catch (e) {
      // Обработка ошибок сети/сервера
    }
  • http — более легковесный официальный пакет от команды Dart. Использую его для простых задач.

2. Сериализация данных: json_serializable + freezed или built_value. Автоматическая генерация кода для преобразования JSON в Dart-объекты и обратно. freezed — особенно удобен, так как создает неизменяемые (immutable) классы с методами copyWith.

    @freezed
    class User with _$User {
      factory User({
        required int id,
        required String name,
        String? email,
      }) = _User;
      factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
    }

3. Управление состоянием и кэширование. Запросы к API интегрируются в общую архитектуру управления состоянием (например, Bloc, Riverpod).

  • Кэширование ответов: Использую dio_http_cache или hive для локального хранения данных.
  • Повторные запросы при восстановлении связи: Пакет connectivity_plus в связке с логикой в Bloc/Cubit.

4. Альтернативные подходы к API:

  • GraphQL: Для проектов со сложными или часто меняющимися требованиями к данным использую пакет graphql_flutter.
  • WebSockets: Для real-time функций (чат, уведомления) — web_socket_channel.
  • gRPC: Для высокопроизводительной внутренней коммуникации в микросервисной архитектуре.

Типичная структура слоя данных:

lib/
  data/
    models/          # Классы моделей (User, Post) с json_serializable
    repositories/    # UserRepository (абстракция)
    datasources/     # UserRemoteDataSource (работа с Dio), UserLocalDataSource (Hive)
  domain/           # Бизнес-логика и use cases
  presentation/     # UI и состояние (Blocs/Providers)

Такой подход обеспечивает тестируемость, разделение ответственности и легкую замену источника данных (например, на мок для тестов).