Можно ли отправить данные в теле DELETE-запроса из Flutter-приложения?

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

Ответ

Технически отправить тело в DELETE-запросе можно, но это противоречит общепринятой практике и может не поддерживаться сервером.

1. Использование пакета http:

import 'package:http/http.dart' as http;

Future<void> deleteWithBody() async {
  final response = await http.delete(
    Uri.parse('https://api.example.com/resource/123'),
    headers: {'Content-Type': 'application/json'},
    body: jsonEncode({'reason': 'obsolete', 'deletedBy': 'user123'}),
  );

  if (response.statusCode == 200) {
    print('Deleted successfully');
  }
}

2. Использование пакета dio (более гибкий):

import 'package:dio/dio.dart';

Future<void> deleteWithDio() async {
  final dio = Dio();
  final response = await dio.delete(
    'https://api.example.com/resource/123',
    data: {'reason': 'obsolete'},
    options: Options(contentType: Headers.jsonContentType),
  );
  print(response.data);
}

Проблемы и рекомендации:

  • Серверная поддержка: Многие фреймворки (Express.js, Spring) по умолчанию игнорируют тело DELETE-запроса
  • Прокси и кэши: Некоторые прокси-серверы могут удалять тело из DELETE-запросов
  • REST-практика: Согласно REST, идентификатор ресурса должен передаваться в URL, а дополнительные параметры — в query-параметрах

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

// 1. Использование query-параметров (рекомендуется)
await http.delete(
  Uri.parse('https://api.example.com/resource/123?reason=obsolete&deletedBy=user123'),
);

// 2. Использование POST для операции удаления с телом
await http.post(
  Uri.parse('https://api.example.com/resource/123/delete'),
  body: jsonEncode({'reason': 'obsolete'}),
);

В Flutter-разработке лучше согласовать формат DELETE-запросов с бэкенд-командой и следовать их API-контракту.