request method
Future<ChalonaResponse>
request(
- String url, {
- Map data = const {},
- String? token,
- List<
ChalonaFile> ? files, - ChalonaHttpContentType contentType = ChalonaHttpContentType.json,
- ChalonaHttpMethod method = ChalonaHttpMethod.post,
override
Realiza una petición HTTP al servidor
url - Ruta relativa a la URL base
data - Datos a enviar en formato JSON
token - Token de autenticación (opcional)
files - Archivos a enviar (no implementado)
Throws:
- TimeoutException si la petición tarda más de 30 segundos
- Exception si el servidor responde con error
Implementation
@override
Future<ChalonaResponse> request(
String url, {
Map data = const {},
String? token,
List<ChalonaFile>? files,
ChalonaHttpContentType contentType = ChalonaHttpContentType.json,
ChalonaHttpMethod method = ChalonaHttpMethod.post,
}) async {
files ??= [];
Map<String, String> headers = {
'Content-Type': contentType.value,
'Accept': contentType.value,
if (token != null) 'Authorization': 'Bearer $token',
};
var chost = host;
if (url.contains('https://') || url.contains('http://')) {
chost = '';
}
var uri;
if (method == ChalonaHttpMethod.get) {
uri = Uri.parse(chost +
url +
(data.isNotEmpty
? '?' +
Uri(
queryParameters: data.map(
(key, value) => MapEntry(key, value.toString())))
.query
: ''));
} else {
uri = Uri.parse(chost + url);
}
Response response;
if (method == ChalonaHttpMethod.get) {
response = await get(uri, headers: headers);
} else if (files.isNotEmpty) {
// Uso de multipart/form-data para solicitudes con archivos
var request = MultipartRequest('POST', uri);
request.headers.addAll(headers);
// Agregar archivos
for (var file in files) {
var multipartFile = MultipartFile.fromString(
'xml',
file.content,
filename: file.fileName,
contentType: MediaType('application', file.type),
);
request.files.add(multipartFile);
}
// Agregar argumentos
request.fields
.addAll(data.map((key, value) => MapEntry(key, value.toString())));
var streamedResponse = await request.send();
response = await Response.fromStream(streamedResponse);
} else if (contentType == ChalonaHttpContentType.formUrlEncoded) {
// Manejo especial para application/x-www-form-urlencoded
Map<String, String> formData = {};
data.forEach((key, value) {
formData[key.toString()] = value.toString();
});
response = await post(
uri,
headers: headers,
body: formData,
encoding: Encoding.getByName('utf-8'),
);
} else {
response = await post(
uri,
headers: headers,
body: jsonEncode(data),
);
}
ChalonaResponse r;
try {
// Intenta decodificar como JSON
var decoded = jsonDecode(response.body);
if (decoded is Map && decoded.containsKey('ok')) {
r = ChalonaResponse(source: MapType.from(decoded));
} else {
r = ChalonaResponse(source: {'data': decoded});
}
} catch (e) {
// Si no es JSON válido, trata como respuesta de texto
r = ChalonaResponse(source: {
'ok': response.statusCode == 200,
'msg': response.statusCode == 200 ? '' : response.body,
'data': response.statusCode == 200
? {
'result': response.body,
}
: {}
});
}
if (response.statusCode != 200 && response.statusCode != 201) {
console.error(response.body);
throw ChalonaResponse(source: {
'ok': false,
'msg': response.body,
'data': {},
});
}
return r;
}