En este tema, aprenderemos cómo integrar APIs REST en nuestras aplicaciones Flutter para obtener y enviar datos a servidores remotos. Este es un aspecto crucial del desarrollo de aplicaciones modernas, ya que permite que nuestras aplicaciones interactúen con servicios web y bases de datos en la nube.

Objetivos de Aprendizaje

  • Comprender qué es una API REST y cómo funciona.
  • Configurar una solicitud HTTP en Flutter.
  • Manejar respuestas de API y errores.
  • Enviar datos a un servidor mediante una API REST.

¿Qué es una API REST?

Una API REST (Representational State Transfer) es un conjunto de reglas que permiten la comunicación entre sistemas a través de HTTP. Las APIs RESTful utilizan métodos HTTP estándar como GET, POST, PUT y DELETE para realizar operaciones CRUD (Crear, Leer, Actualizar, Eliminar).

Métodos HTTP Comunes

Método Descripción
GET Recupera datos del servidor.
POST Envía datos al servidor para crear un nuevo recurso.
PUT Actualiza un recurso existente en el servidor.
DELETE Elimina un recurso del servidor.

Configuración de una Solicitud HTTP en Flutter

Para realizar solicitudes HTTP en Flutter, utilizaremos el paquete http. Asegúrate de agregarlo a tu archivo pubspec.yaml:

dependencies:
  flutter:
    sdk: flutter
  http: ^0.13.3

Luego, importa el paquete en tu archivo Dart:

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

Realizando una Solicitud GET

Vamos a realizar una solicitud GET para obtener datos de una API pública. Por ejemplo, usaremos la API de JSONPlaceholder para obtener una lista de posts.

Future<void> fetchPosts() async {
  final response = await http.get(Uri.parse('https://jsonplaceholder.typicode.com/posts'));

  if (response.statusCode == 200) {
    List<dynamic> posts = jsonDecode(response.body);
    print(posts);
  } else {
    throw Exception('Failed to load posts');
  }
}

Explicación del Código

  1. Importaciones: Importamos el paquete http y dart:convert para manejar las solicitudes HTTP y la conversión de JSON.
  2. Solicitud GET: Utilizamos http.get para realizar una solicitud GET a la URL de la API.
  3. Manejo de Respuesta: Verificamos si el statusCode de la respuesta es 200 (OK). Si es así, decodificamos el cuerpo de la respuesta JSON y lo imprimimos. Si no, lanzamos una excepción.

Enviando Datos con una Solicitud POST

Para enviar datos a un servidor, utilizamos el método POST. Vamos a enviar un nuevo post a la API de JSONPlaceholder.

Future<void> createPost(String title, String body) async {
  final response = await http.post(
    Uri.parse('https://jsonplaceholder.typicode.com/posts'),
    headers: <String, String>{
      'Content-Type': 'application/json; charset=UTF-8',
    },
    body: jsonEncode(<String, String>{
      'title': title,
      'body': body,
      'userId': '1',
    }),
  );

  if (response.statusCode == 201) {
    print('Post created: ${response.body}');
  } else {
    throw Exception('Failed to create post');
  }
}

Explicación del Código

  1. Solicitud POST: Utilizamos http.post para enviar una solicitud POST a la URL de la API.
  2. Encabezados: Especificamos los encabezados de la solicitud, indicando que el contenido es JSON.
  3. Cuerpo de la Solicitud: Codificamos el cuerpo de la solicitud en JSON.
  4. Manejo de Respuesta: Verificamos si el statusCode de la respuesta es 201 (Created). Si es así, imprimimos la respuesta. Si no, lanzamos una excepción.

Manejo de Errores

Es importante manejar los errores que pueden ocurrir durante las solicitudes HTTP. Aquí hay un ejemplo de cómo hacerlo:

Future<void> fetchPosts() async {
  try {
    final response = await http.get(Uri.parse('https://jsonplaceholder.typicode.com/posts'));

    if (response.statusCode == 200) {
      List<dynamic> posts = jsonDecode(response.body);
      print(posts);
    } else {
      throw Exception('Failed to load posts');
    }
  } catch (e) {
    print('Error: $e');
  }
}

Explicación del Código

  1. Bloque try-catch: Envolvemos la solicitud HTTP en un bloque try-catch para capturar cualquier excepción que pueda ocurrir.
  2. Manejo de Excepciones: Si ocurre una excepción, la capturamos y la imprimimos.

Ejercicio Práctico

Ejercicio

  1. Crea una aplicación Flutter que obtenga una lista de usuarios de la API de JSONPlaceholder (https://jsonplaceholder.typicode.com/users) y los muestre en una lista.
  2. Agrega una funcionalidad para crear un nuevo usuario utilizando una solicitud POST.

Solución

Paso 1: Crear la Función para Obtener Usuarios

Future<List<dynamic>> fetchUsers() async {
  final response = await http.get(Uri.parse('https://jsonplaceholder.typicode.com/users'));

  if (response.statusCode == 200) {
    return jsonDecode(response.body);
  } else {
    throw Exception('Failed to load users');
  }
}

Paso 2: Mostrar Usuarios en una Lista

class UserList extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return FutureBuilder<List<dynamic>>(
      future: fetchUsers(),
      builder: (context, snapshot) {
        if (snapshot.connectionState == ConnectionState.waiting) {
          return CircularProgressIndicator();
        } else if (snapshot.hasError) {
          return Text('Error: ${snapshot.error}');
        } else {
          return ListView.builder(
            itemCount: snapshot.data?.length ?? 0,
            itemBuilder: (context, index) {
              return ListTile(
                title: Text(snapshot.data[index]['name']),
                subtitle: Text(snapshot.data[index]['email']),
              );
            },
          );
        }
      },
    );
  }
}

Paso 3: Crear la Función para Enviar Datos

Future<void> createUser(String name, String email) async {
  final response = await http.post(
    Uri.parse('https://jsonplaceholder.typicode.com/users'),
    headers: <String, String>{
      'Content-Type': 'application/json; charset=UTF-8',
    },
    body: jsonEncode(<String, String>{
      'name': name,
      'email': email,
    }),
  );

  if (response.statusCode == 201) {
    print('User created: ${response.body}');
  } else {
    throw Exception('Failed to create user');
  }
}

Resumen

En esta lección, hemos aprendido cómo integrar APIs REST en nuestras aplicaciones Flutter utilizando el paquete http. Hemos cubierto cómo realizar solicitudes GET y POST, manejar respuestas y errores, y enviar datos al servidor. Estos conceptos son fundamentales para construir aplicaciones que interactúan con servicios web y bases de datos en la nube.

En el próximo módulo, exploraremos cómo manejar la persistencia y el almacenamiento de datos en Flutter.

Curso de Desarrollo con Flutter

Módulo 1: Introducción a Flutter

Módulo 2: Conceptos Básicos de Programación en Dart

Módulo 3: Widgets en Flutter

Módulo 4: Gestión de Estado

Módulo 5: Navegación y Enrutamiento

Módulo 6: Redes y APIs

Módulo 7: Persistencia y Almacenamiento

Módulo 8: Conceptos Avanzados de Flutter

Módulo 9: Pruebas y Depuración

Módulo 10: Despliegue y Mantenimiento

Módulo 11: Flutter para Web y Escritorio

© Copyright 2024. Todos los derechos reservados