En cualquier aplicación hoy en día, es necesario poder comunicarse con Internet para poder obtener datos, en Flutter no es la excepción, ya sea que quieras crear aplicaciones web o móviles con el mismo, debes de conocer como realizar este tipo de conexiones o integraciones, en este tutorial, abordaremos este tema.
Las aplicaciones móviles son muy características y usualmente necesitan conectarse a los servidores para poder construir la app; mi aplicación de Academia, tanto la web que es echa en Vue como la móvil con Android es un ejemplo de esto, si esa data obtenida mediante una solicitud o petición HTTP NO servirían para nada.
En este artículo, creará una aplicación Flutter de ejemplo que usa el paquete http para realizar solicitudes HTTP.
Nos quedamos en que, aprendimos a como mostrar modals deslizantes con los showModalBottomSheet en Flutter.
¿Por qué necesitas HTTP en una app Flutter?
Hoy prácticamente cualquier app necesita hablar con un servidor: obtener datos, enviar formularios, actualizar usuarios, validar autenticación… y Flutter no es la excepción. De hecho, una de las razones por las que uso Flutter desde hace años es porque integra muy bien el trabajo con APIs REST sin importar si la app es móvil o web.
Ejemplos de uso reales
En mis proyectos, lo más común es consumir APIs hechas en Laravel, CodeIgniter o Django. De hecho, si has seguido mis cursos, ya habrás visto que casi todo lo que hacemos implica conexiones HTTP para intercomunicar sistemas. Flutter lo hace muy fácil con su paquete http.
La misma app de Academia, uso este paquete para hacer las solicitudes HTTP.
Principios del Protocolo HTTP
HTTP es simplemente el lenguaje con el que “Cliente” (app Flutter) y “Servidor” (API) se comunican. Cada mensaje que envía la app es una solicitud HTTP, y la API responde con datos, generalmente en formato JSON.
HTTP (Protocolo de transferencia de hipertexto) se utiliza para la comunicación efectiva entre el "Cliente" y el "Servidor" y el mensaje que envía un cliente a un servidor se conoce como "solicitud HTTP" y que si has tomado mis cursos, ya tu debes de conocer ya que siempre hacemos conexiones de tipo HTTP para intercomunicar sistemas y en Flutter no es la excepción.
Flutter admite funciones como la solicitud HTTP de todo tipo para interconectar sistemas webs creadas en Laravel, CodeIgniter... Django, Flash... o cualquier cosa que emplee peticiones HTTP con Flutter lo cual es punto.
Configurando tu proyecto Flutter para hacer peticiones HTTP
Vamos a ver paso a paso como configurar nuestra aplicación para poder realizar peticiones HTTP ya que, en el caso de Flutter necesitamos instalar un paquete para poder habilitar esta operación.
1: Lo primero es agregar el paquete http al archivo pubspec.yaml y ejecutar pub get:
https://pub.dev/packages/http
Este paquete nos permite realizar peticiones HTTP fácilmente a cualquier otra aplicación, inclusive la que nosotros realizamos.
dependencies:
http: 2: importar el paquete http:
import 'package:http/http.dart' as http;Le colocamos el alias de as http para que podamos referenciar todos los métodos que nos ofrece este paquete mediante http.
Luego ejecuta:
$ flutter pub get3: Crea una función para enviar una petición de tipo get:
Aquí puedes ver un código que se auto explica solo bastante bien: lo primero que necesitamos es definir el String de conexión mediante una Uri, la cual pasamos de un String a una uri.
El siguiente es realizar la petición, que puede ser de cualquier tipo, y en este caso es una petición de tipo post a la ruta anterior y pasamos unos parámetros de manera de ejemplo: como puedes suponer, al ser una petición a internet, esto demora algo de tiempo que NO sabemos determinar y por eso colocamos un await.
Finalmente tenemos la respuesta y podemos preguntar por distintos datos como el status, headers y por supuesto el body que nos trae los datos de respuesta.
var url = Uri.parse('tu-sitio');
var response = await http.post(url, body: {'name': 'doodle', 'color': 'blue'});
print('Response status: ${response.statusCode}');
print('Response body: ${response.body}');
print(await http.read('https://example.com/foobar.txt'));Explicación de la función anterior
- http.response (utilizado para solicitar los datos de la URL y almacenar la respuesta)
- Ahora guarde la respuesta en la variable de respuesta response = await http.get (Uri.parse (“tu-sitio"));
- Aquí estamos analizando la URL porque la URL consta de datos sin procesar y no podemos usarla.
- Ahora tenemos que decodificar o analizar el json usando json.decode (response.body) tomado de dart: convert package
- En el paso anterior decodificamos el cuerpo porque los datos sin procesar están presentes en el cuerpo de la respuesta
- Más métodos
- Por supuesto podemos realizar distintos tipos de conexión con métodos de tipo get, post, put, patch, delete...
Tipos de solicitudes HTTP en Flutter
Las APIs REST más comunes trabajan con estos cinco métodos: GET, POST, PUT, PATCH y DELETE. Aquí te explico cómo usarlos.
GET — Obtener datos
final res = await http.get(Uri.parse("http://10.0.2.2:1337/products"));
final List<dynamic> data = json.decode(res.body);Las peticiones GET son las que más uso para cargar datos al inicio de una pantalla.
POST — Enviar datos
final res = await http.post(
Uri.parse('http://10.0.2.2:1337/auth/local'),
body: {
"identifier": _emailController.text,
"password": _passwordController.text,
},
);Uso POST para login o formularios. Aquí es normal que la API responda con un token JWT, que luego uso en otras peticiones.
PUT / PATCH — Actualizar recursos
Para actualizar registros:
final res = await http.put(
Uri.parse("http://10.0.2.2:1337/favorites/${user.favoriteId}"),
body: {
"products": json.encode(productsFavoriteId),
},
headers: {
"Authorization": "Bearer ${user.jwt}"
},
);Aquí combino body + headers.
DELETE — Eliminar recursos
await http.delete(Uri.parse('https://api.com/items/1'));Trabajando con JSON: decodificar y codificar
- Usar json.decode y json.encode
El servidor responde con texto plano, así que debes decodificarlo:
final resData = json.decode(res.body);Cuando envío listas o mapas, siempre uso:
json.encode(miMapa);Mapear JSON a modelos de Dart
Aunque a veces imprimo directamente el body para depurar, en producción creo modelos usando fromJson y toJson.
Manejo de errores y buenas prácticas
Comprobar statusCode:
if (res.statusCode == 200) {
final data = json.decode(res.body);
} else {
print("Error: ${res.statusCode}");
}Como recomendación, siempre pero siempre revisa el código de estado, ya que, a la primera que haces cambios da un error y es difícil de detectar si primero NO verificas el código de estado del servidor. Status 401, 403, 500… pasan más seguido de lo que imaginas.
Timeout y reintentos
Flutter permite ajustar un timeout:
await http.get(url).timeout(Duration(seconds: 10));Seguridad: headers y autenticación
Casi siempre uso Bearer tokens:
headers: {
"Authorization": "Bearer ${user.jwt}",
}Depuración y monitoreo de peticiones HTTP
Logs y herramientas
En desarrollo me apoyo muchísimo en:
- print() para inspeccionar respuestas
- Inspección de la API con Postman
- Verificar URLs (muchos errores vienen de un simple slash mal puesto)
Cuando una vez mi API fallaba “misteriosamente”, terminé descubriendo que era un JSON mal formateado. Una impresión del body lo resolvió.
Ejemplo completo: consumir una API REST en Flutter
Aquí tienes una estructura típica que uso:
Servicio HTTP
class ApiService {
final baseUrl = "http://10.0.2.2:1337";
Future<dynamic> getProducts() async {
final res = await http.get(Uri.parse("$baseUrl/products"));
if (res.statusCode == 200) {
return json.decode(res.body);
} else {
throw Exception("Error al obtener productos");
}
}
}Uso en un Widget
FutureBuilder(
future: ApiService().getProducts(),
builder: (_, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return CircularProgressIndicator();
}
if (snapshot.hasError) return Text("Error");
final data = snapshot.data;
return ListView.builder(
itemCount: data.length,
itemBuilder: (_, i) => Text(data[i]["name"]),
);
},
)Algunos ejemplos que te pueden interesar y que forman parte de mi curso de Flutter.
En este primer ejemplo vemos como realizar peticiones PUT para actualizar contenido pasando un parámetro de identificador mediante la URL; además de, pasar mediante el body un campo llamado products” el cual no es mas que una lista de identificadores, también, vemos como usar los headers, en este caso, para pasar el token de autenticación:
final res = await http.put(
Uri.parse("http://10.0.2.2:1337/favorites/${user.favoriteId}"),
body: {
"products": json.encode(productsFavoriteId),
},
headers: {
"Authorization": "Bearer ${user.jwt}"
});En este segundo ejemplo, vemos como realizar una petición tipo GET a un dominio, pasando un identificador y protección mediante token de autenticación; luego, evaluamos la respuesta para saber si la misma fue satisfactoria mediante una petición 200:
final res = await http.get(
Uri.parse("http://10.0.2.2:1337/favorites/${user.favoriteId}"),
headers: {"Authorization": "Bearer ${user.jwt}"});
print(res.statusCode);
if (res.statusCode == 200) {
final resData = json.decode(res.body);
}En este segundo ejemplo, vemos como enviar une petición post con dos campos suministrados en el body:
final res = await http.get(Uri.parse("http://10.0.2.2:1337/products"));
final List<dynamic> resData = json.decode(res.body);
final res = await http.post(Uri.parse('http://10.0.2.2:1337/auth/local'), body: {
"identifier": _emailController.text,
"password": _passwordController.text,
});En todos los casos, es importante recordar que, son peticiones asíncronas, cualquier tipo de peticiones que no forme parte de la aplicación, si no de medios externos, como acceder al disco, una memoria o en este caso, una petición HTTP, se realizan mediante procesos asíncronos.
Errores comunes y cómo resolverlos
- CORS
- Si usas Flutter Web, habilita CORS en tu API.
- JSON mal formateado
- Siempre imprime el body cuando algo “no cuadra”.
- Token inválido o vencido
- Si recibes un 401, refresca el token.
Consejos
- Cachear respuestas
- Ideal para apps que cargan catálogos o listas estáticas.
- Usar librerías más potentes
- Aunque http es suficiente para la mayoría de mis proyectos, cuando necesito interceptores, cancelación de requests o multipart, uso dio.
- ¿Cuándo usar WebSockets?
- Cuando necesitas datos en tiempo real (chat, pedidos, notificaciones).
Conclusión
Hacer peticiones HTTP en Flutter es sencillo, flexible y potente gracias al paquete http. Puedes consumir APIs REST, manejar autenticación, enviar datos, actualizar recursos y depurar errores con relativa facilidad.
Cuando empecé a trabajar con Flutter, una de las primeras cosas que noté es que las peticiones son totalmente asíncronas, igual que en otros frameworks modernos. Esto evita bloqueos y hace que tu app se mantenga fluida mientras recibe datos de Internet.
Preguntas frecuentes (FAQ)
- ¿Qué paquete uso para hacer solicitudes HTTP en Flutter?
- Generalmente http, aunque dio es una alternativa avanzada.
- ¿Cómo decodifico respuestas JSON?
- Usa json.decode(response.body).
- ¿Cómo envío autenticación?
- Con headers: "Authorization": "Bearer token".
- ¿GET o POST?
- GET para obtener datos, POST para enviar o autenticar.
Ahora, aprende a persistir estos datos en Flutter mediante SharedPreferences.
Acepto recibir anuncios de interes sobre este Blog.
Enviar peticiones HTTP desde una app en Flutter es posible, NECESARIO y muy fácil con un paquete; es fundamental para interconectar aplicaciones; Aprende como!