tl;dr desarrollando un pequeño sideproject me encontré con la necesidad de disponer de un API para servir información que variaría con poca frecuencia a las aplicaciones móviles. En vez de desarrollar un backend y mantener un hosting usé una hoja de Google Spreadsheet.

Durante estos días de cuarentena, he estado desarrollando una aplicación móvil en flutter. Esta aplicación tiene una pantalla en la que necesito poder actualizar los datos sin necesidad de lanzar una nueva versión en la Play Store, pero tampoco quiero tener que desarrollar una API por que la idea del proyecto era, justamente hacerlo más sencillo posible y sin costes de mantenimiento como el que supone un servidor.

Anteriormente había usado, para cosas similares, un JSON servido estáticamente con GitHub Pages y esto funciona, pero es un poco rollo tener que editar manualmente un archivo JSON que además, en este caso, incluía textos largos escritos en markdown.

Al final di con la solución más sencilla y eficiente. ¡Una hora de Google Spreadsheet!

Sheety.co

Esta web nos permite, de forma sencilla, crear una API a partir de una hoja de Google Spreadsheet recibiendo, en nuestra aplicación, un JSON con los datos de esta.

Lo mejor es que, si quieres cambiar algún dato, simplemente debes acceder a la hoja en cuestión, modificarla a tu gusto y listo.

¿Cómo hacer una petición http en flutter?

Una vez creado el documento y obtenido la url pública simplemente tenemos que, en flutter, hacer la petición y parsearlo. Pongamos de ejemplo que tenemos un documento de Spreadsheet que nos devuelve personas con una id, nombre y correo electrónico. Algo así:

| Id | Name   | Email                |
|----|--------|----------------------|
| 1  | Víctor | hola@victorfalcon.es |
| 2  | Jhon   | jhon@doe.com         |

Para obtenerlo en nuestra aplicación y trabajar con estos datos lo primero que tenemos que hacer es definir el objeto. En este caso le llamaremos Contact. Este objeto, como vemos a continuación.

Además de definir los parámetros deberemos de definir un constructor a partir de un map que contendrá cada columna de la hoja de cálculo anterior a partir de la cual construiremos nuestro objecto.

class Contact {
  int id;
  String name;
  String email;

  Contact(this.id, this.name, this.email);
  
  // Constructor a partir del json de respuesta
  factory Contact.fromJson(Map<String, dynamic> json) {
    return Contact(
      json['id'],
      json['name'],
      json['email'],
    );
  }
}

Luego tenemos que hacer la petición y parsear la respuesta:

Future<void> getContacts() async {
    // Previamente definimos la variable _apiPath con la ruta a nuestra
    // API de la cual obtendrémos la respuesta esperada
	Response _response = await client.get(_apiPath);
    
    final parsed = jsonDecode(_response.body)['sheet1']
        .cast<Map<String, dynamic>>();
        
    List<Contact> contacts = parsed
        .map<Contact>((json) => Contact.fromJson(json))
        .toList();
        
    return contacts;
}

Y con esto sería suficiente para obtener esa lista de contactos a partir de nuestra API creada en segundos. Cabe destacar que el código anterior he usado la librería http de dart para hacer la petición a la API.