Desmitificando la API de cambios de Google Drive - Emptor
Hace poco lanzamos nuestra nueva integración con Google Sheets, proporcionando una interfaz de usuario a nuestra API de verificación de antecedentes. Nuestros clientes realmente les gusta esta nueva forma de interactuar con nuestra API, ya que reduce su carga de trabajo y simplifica el proceso de revisión. Los clientes obtienen una hoja de cálculo y voilá — no necesitan construir nada para utilizar nuestro sistema. Pueden colocar los datos del perfil en la hoja de cálculo proporcionada y los resultados se publican tan pronto como se completa la verificación de antecedentes para cada perfil. No es cohete espacial: queremos hacer que todo sea lo más fácil posible para nuestros clientes.
Dado que nuestra infraestructura de productos se basa en servicios distintos de la plataforma Google Cloud, traerlos a nuestra pila de desarrollo planteó algunos desafíos para nosotros durante el desarrollo de esta herramienta. Nos llevó unas semanas de planificación antes de llegar a comprender que nuestra principal preocupación era encontrar una forma que le diera a nuestros clientes el poder de iniciar tantas ejecuciones de verificación de antecedentes como fuera necesario, de la manera más limpia y sencilla posible.
Con ese objetivo en mente, desarrollamos un complemento de Google Sheets que permite a los clientes iniciar el proceso. Sin embargo, no funcionó de acuerdo a nuestras expectativas, y necesitábamos un complemento privado con Google Sheets compartido fuera de nuestra organización de GCP. Desafortunadamente, descubrimos que no es posible con el conjunto de funciones actual ofrecido por un complemento de Google Sheets.
A continuación, construimos una solución basada en sondeo que verifica todas las hojas de cálculo de todos nuestros clientes cada pocos minutos. Pero esa solución solo es eficiente con un pequeño número de hojas de cálculo debido al hecho de que la API de Google Sheets ofrece una cuota muy limitada (es decir, 100 solicitudes/100 segundos). Comenzamos a enfrentar problemas de escalabilidad a medida que incorporábamos más clientes a este nuevo producto y concluimos que necesitábamos un sistema que verifique solo ciertas hojas de cálculo, aquellas que han tenido cambios realizados por el propietario de la hoja de cálculo.
Para lograr nuestro nuevo objetivo, nos sumergimos en la API de cambios de Google Drive, que parecía prometedora. La API de Google Drive ofrece dos métodos para leer los cambios, aunque, en realidad, solo proporciona un método, y el segundo método está diseñado para integrarse con el primer método para evitar hacer solicitudes innecesarias.
Método #1: Sondeo con Changes.list
Este es un método bastante sencillo. Sin embargo, requiere sondear el mismo extremo continuamente para recibir los cambios. Así es como funciona:
-
Recupere el token de página de inicio usando el extremo
Changes.getStartPageToken
. Devuelve el siguiente objeto JSON como respuesta:{ "kind": "drive#startPageToken", "startPageToken": "string" }
-
Use ese token para recuperar los elementos de cambio usando el extremo
Changes.list
. Esto también proporcionará un token de página siguiente. Devuelve el siguiente objeto JSON como respuesta:{ "kind": "drive#changeList", "nextPageToken": "string", "newStartPageToken": "string", "changes": [ "changes Resource" ] }
Donde cada elemento de cambio es como el siguiente objeto JSON:
{ "kind": "drive#change", "type": "string", "changeType": "string", "time": "datetime", "removed": "boolean", "fileId": "string", "file": "files Resource", "teamDriveId": "string", "driveId": "string", "teamDrive": "teamdrives Resource", "drive": "drives Resource" }
-
Repita el Paso 2 con el token de página siguiente recibido en el Paso 2.
La única parte complicada de este método es que para seguir recibiendo los cambios, el sistema necesita hacer solicitudes continuas con los tokens nextPageToken
. Es un bucle interminable.
Método #2: Notificaciones push con Changes.watch
Este método agrega una capa encima del primer método, usando una URL de webhook para solucionar ese bucle interminable. Con este método, ya no necesitamos sondear. Cada vez que ocurre un cambio, Google hace una solicitud HTTP POST vacía a la URL de webhook que registramos. Así es como funciona:
- Registre su dominio en la Consola de búsqueda de Google usando el método de dominio. El método de prefijo de URL no funcionará porque su dominio también debe estar registrado con su proyecto de GCP, que no admite prefijo de URL.
- Registre su URL usando el extremo
Changes.watch
.
A partir de este punto, por cada cambio que ocurra, Google hará una solicitud HTTP POST con un cuerpo vacío a la URL que acaba de registrar. Devuelve el siguiente objeto JSON en la respuesta para registrar la URL del Webhook:
{
"kind": "api#channel",
"id": "string",
"resourceId": "string",
"resourceUri": "string",
"token": "string",
"expiration": "long",
"type": "string",
"address": "string",
"payload": "boolean",
"params": { "(key)": "string" }
}
Tenga en cuenta que este paso debe integrarse con el primer método. Por cada solicitud POST que reciba su URL, debe hacer una sola solicitud al extremo Changes.list
para obtener realmente la lista de cambios y luego procesarlos. En otras palabras, este es el punto donde comienza el primer método. Pero en lugar de sondear, solo hace la solicitud cuando hay notificaciones.
Si desea anular el registro de su URL de webhook y dejar de recibir las notificaciones de cambio, puede hacer una solicitud HTTP POST a Channels.stop
para hacer eso.
Comparación de los dos métodos
Título | Notificaciones push | Sondeo |
---|---|---|
Sondeo | – No se necesita | – Se necesita |
Obtención de cambios | – Por cada cambio, se llama a la URL de webhook registrada sin elemento de cambio | – Hacer una solicitud de sondeo devuelve una lista de elementos de cambio, con la opción de limitar la cantidad de cambios recibidos por solicitud |
Vencimiento del webhook | – El registro del webhook caduca después de una semana; el tiempo de espera predeterminado se establece en una hora | – No hay vencimiento |
Elementos de cambio duplicados | – Es posible que haya cambios duplicados. Tenga en cuenta que es probable que haya un período de “superposición” de tiempo cuando los dos canales de notificación para el mismo recurso estén activos. | – Cada token es una referencia a una lista de elementos de cambio. Debería ser responsabilidad del extremo devolver elementos de cambio sin duplicar |
URL del webhook | – Se requiere una URL de webhook accesible públicamente para ser registrada con la API | – No se requiere URL de webhook |
Criterio de elemento de cambio | – Abrir un archivo no se considera un elemento de cambio | – Abrir un archivo se considera un elemento de cambio. Esto ocurre debido al cambio en la información de metadatos que almacena los valores de fecha/hora |
Elementos de cambio antiguos | – Solo incluye los cambios realizados después de que se registró el webhook | – Aproximadamente 2 meses de cambios antiguos se recuperan si se usa un nuevo token de página de inicio. Esto se puede evitar almacenando y usando el último token utilizado |
Lamentablemente, estos métodos no proporcionan información sobre el cambio real que se realizó. Si bien incluye el fileId
en el elemento de cambio, tampoco especifica quién hizo el cambio o a qué hora se realizó. Por ejemplo, no dice: “John modificó la Columna 3 de la Fila 5 del archivo XYZ el 14 de agosto de 2020 a las 5:00 a.m.”. Simplemente dice que “El archivo XYZ tiene un cambio”.
Afortunadamente, la API de Google Drive también proporciona la API de revisiones, que puede ayudarnos a descubrir más detalles sobre el cambio que ocurrió. Con ella, se puede recuperar un historial de revisiones para un archivo específico usando el extremo Revisions.list
, donde cada elemento de revisión se ve algo así:
{
"kind": "api#channel",
"id": "string",
"resourceId": "string",
"resourceUri": "string",
"token": "string",
"expiration": "long",
"type": "string",
"address": "string",
"payload": "boolean",
"params": { "(key)": "string" }
}
¡Hurra! Ahora sabemos el último modifiedTime
y el usuario que lo modificó (a través de lastModifyingUser
).
Pero espera, ¿y si ese último elemento de revisión de la lista de revisiones se agregó justo antes de que lo recuperaras? ¿Y si el elemento de revisión que buscabas viene antes? ¿Y si el tiempo que recibiste el elemento de cambio fue mucho más tarde de cuando realmente ocurrió el cambio? ¿Cómo nos aseguramos de recibir el cambio a tiempo? ¿Cómo sabemos que el historial de revisiones contiene el elemento exacto que esperamos procesar? La lista de preguntas continúa y no hay respuestas obvias.
La API de Google Drive puede funcionar para muchos problemas, pero los problemas que necesitamos resolver requieren varias funciones que creemos que actualmente faltan en esta API. Necesitamos una forma de poder recibir el elemento de cambio cuando ocurra, junto con toda la información relevante relacionada con él. La API de Google Drive parecía ser una utilidad prometedora, pero después de que pasamos algún tiempo investigando todos sus oscuros secretos, resultó que no puede cumplir con nuestras necesidades actuales. Además, los recursos (costo y tiempo) necesarios para construir una solución basada en las funciones existentes de la API de Google Drive son mucho más caros que sus beneficios.
Google Sheets es genial para nuestros clientes, y actualmente estamos trabajando para traer un sistema avanzado para nuestros clientes con una interfaz de usuario sólida que eventualmente reemplazará esta integración. Proporcionará una experiencia amigable para el consumidor de nuestra API con varias nuevas funciones. Junto con eso, también lanzaremos un wrapper de Python de código abierto para nuestra API para permitir que nuestros clientes construyan sus propias soluciones personalizadas utilizando nuestra API.
Esperamos que ahora tengas una mejor comprensión de cómo funciona la API de Google Drive y cómo puede (y no puede) satisfacer tus necesidades.
Realiza verificaciones de antecedentes en LATAM con Emptor.