Reach

Grow

Manage

Automate

Reach

Grow

Manage

Automate

Mejores Prácticas para la Versionado de APIs RESTful: Por qué v1 es el número 1

Correo electrónico

1 min read

Mejores Prácticas para la Versionado de APIs RESTful: Por qué v1 es el número 1

Correo electrónico

1 min read

Mejores Prácticas para la Versionado de APIs RESTful: Por qué v1 es el número 1

¿Entonces, qué tan difícil puede ser versionar una API? La verdad es que no lo es, pero lo que es duro es mantener un poco de cordura al no caer innecesariamente en un número desconcertante de versiones y subversiones aplicadas a docenas de puntos finales de la API con compatibilidades poco claras.

Breaking Changes Malos! API Versioning Bueno!

Como cualquiera que haya construido o use regularmente una API se da cuenta tarde o temprano, los cambios que rompen son muy malos y pueden ser una mancha muy seria en una API que de otra manera sería útil. Un cambio que rompe es un cambio en el comportamiento de una API que puede romper la integración de un usuario y resultar en mucha frustración y pérdida de confianza entre el proveedor de la API y el usuario. Los cambios que rompen requieren que se notifique a los usuarios con antelación (con el correspondiente mea culpa) en lugar de un cambio que simplemente aparece, como una nueva y encantadora funcionalidad. La manera de evitar esa frustración es versionar una API con garantías del propietario de la API de que no se introducirán cambios sorprendentes dentro de una sola versión.

Entonces, ¿qué tan difícil puede ser versionar una API? La verdad es que no lo es, pero lo que sí es difícil es mantener algo de cordura al no degenerar innecesariamente en un mareante número de versiones y subversiones aplicadas a través de docenas de puntos finales de API con compatibilidades poco claras.

Introdujimos la v1 de la API hace tres años y no nos dimos cuenta de que se mantendría fuerte hasta el día de hoy. Entonces, ¿cómo hemos continuado proporcionando la mejor API de entrega de correo electrónico durante más de dos años y aún mantenemos la misma versión de API? Mientras hay muchas opiniones diferentes sobre cómo versionar las APIs REST, espero que la historia de nuestra humilde pero poderosa v1 pueda guiarte en tu camino hacia la iluminación en la versionado de APIs.

REST Es Mejor

La API de SparkPost se origina de cuando éramos Message Systems, antes de nuestras aventuras en la nube. En ese momento estábamos ocupados haciendo los preparativos finales para el lanzamiento beta de Momentum 4. Esta fue una gran actualización de la versión 3.x, nuestro MTA líder en el mercado local. Momentum 4 incluía una interfaz de usuario completamente nueva, análisis en tiempo real y, lo más importante, una nueva API web para la inyección y generación de mensajes, la gestión de plantillas y la obtención de métricas de correo electrónico. Nuestra visión era una arquitectura basada en API primero, donde incluso la interfaz de usuario interactuaría con los puntos finales de la API.

Una de las primeras y mejores decisiones que tomamos fue adoptar un estilo RESTful. Desde finales de la década de 2000, las API web basadas en transferencia de estado representacional (REST) son el estándar de facto de las API en la nube. Usar HTTP y JSON lo hace fácil para los desarrolladores, independientemente del lenguaje de programación que usen: PHP, Ruby y Java, para integrarse con nuestra API sin saber o preocuparse por nuestra tecnología subyacente.

Elegir usar la arquitectura RESTful fue fácil. Elegir una convención de versionado no fue tan fácil. Inicialmente pospusimos la cuestión del versionado al no versionar la beta en absoluto. Sin embargo, dentro de un par de meses, la beta estaba en manos de algunos clientes y comenzamos a desarrollar nuestro servicio en la nube. Era hora de versionar. Evaluamos dos convenciones de versionado. La primera fue poner la versión directamente en el URI y la segunda fue usar un encabezado Accept. La primera opción es más explícita y menos complicada, lo cual es más fácil para los desarrolladores. Como amamos a los desarrolladores, fue la elección lógica.

La API de SparkPost se origina de cuando éramos Message Systems, antes de nuestras aventuras en la nube. En ese momento estábamos ocupados haciendo los preparativos finales para el lanzamiento beta de Momentum 4. Esta fue una gran actualización de la versión 3.x, nuestro MTA líder en el mercado local. Momentum 4 incluía una interfaz de usuario completamente nueva, análisis en tiempo real y, lo más importante, una nueva API web para la inyección y generación de mensajes, la gestión de plantillas y la obtención de métricas de correo electrónico. Nuestra visión era una arquitectura basada en API primero, donde incluso la interfaz de usuario interactuaría con los puntos finales de la API.

Una de las primeras y mejores decisiones que tomamos fue adoptar un estilo RESTful. Desde finales de la década de 2000, las API web basadas en transferencia de estado representacional (REST) son el estándar de facto de las API en la nube. Usar HTTP y JSON lo hace fácil para los desarrolladores, independientemente del lenguaje de programación que usen: PHP, Ruby y Java, para integrarse con nuestra API sin saber o preocuparse por nuestra tecnología subyacente.

Elegir usar la arquitectura RESTful fue fácil. Elegir una convención de versionado no fue tan fácil. Inicialmente pospusimos la cuestión del versionado al no versionar la beta en absoluto. Sin embargo, dentro de un par de meses, la beta estaba en manos de algunos clientes y comenzamos a desarrollar nuestro servicio en la nube. Era hora de versionar. Evaluamos dos convenciones de versionado. La primera fue poner la versión directamente en el URI y la segunda fue usar un encabezado Accept. La primera opción es más explícita y menos complicada, lo cual es más fácil para los desarrolladores. Como amamos a los desarrolladores, fue la elección lógica.

La API de SparkPost se origina de cuando éramos Message Systems, antes de nuestras aventuras en la nube. En ese momento estábamos ocupados haciendo los preparativos finales para el lanzamiento beta de Momentum 4. Esta fue una gran actualización de la versión 3.x, nuestro MTA líder en el mercado local. Momentum 4 incluía una interfaz de usuario completamente nueva, análisis en tiempo real y, lo más importante, una nueva API web para la inyección y generación de mensajes, la gestión de plantillas y la obtención de métricas de correo electrónico. Nuestra visión era una arquitectura basada en API primero, donde incluso la interfaz de usuario interactuaría con los puntos finales de la API.

Una de las primeras y mejores decisiones que tomamos fue adoptar un estilo RESTful. Desde finales de la década de 2000, las API web basadas en transferencia de estado representacional (REST) son el estándar de facto de las API en la nube. Usar HTTP y JSON lo hace fácil para los desarrolladores, independientemente del lenguaje de programación que usen: PHP, Ruby y Java, para integrarse con nuestra API sin saber o preocuparse por nuestra tecnología subyacente.

Elegir usar la arquitectura RESTful fue fácil. Elegir una convención de versionado no fue tan fácil. Inicialmente pospusimos la cuestión del versionado al no versionar la beta en absoluto. Sin embargo, dentro de un par de meses, la beta estaba en manos de algunos clientes y comenzamos a desarrollar nuestro servicio en la nube. Era hora de versionar. Evaluamos dos convenciones de versionado. La primera fue poner la versión directamente en el URI y la segunda fue usar un encabezado Accept. La primera opción es más explícita y menos complicada, lo cual es más fácil para los desarrolladores. Como amamos a los desarrolladores, fue la elección lógica.

Gobernanza API

Con una convención de versionado seleccionada teníamos más preguntas. ¿Cuándo aumentaríamos la versión? ¿Qué es un cambio importante?  ¿Revercionaríamos toda la API o solo ciertos puntos finales? En SparkPost, tenemos múltiples equipos trabajando en diferentes partes de nuestra API. Dentro de esos equipos, las personas trabajan en diferentes puntos finales en diferentes momentos. Por lo tanto, es muy importante que nuestra API sea consistente en el uso de convenciones. Esto era más grande que el versionado.

Establecimos un grupo de gobernanza que incluía ingenieros que representaban a cada equipo, un miembro del equipo de Product Management y nuestro CTO. Este grupo es responsable de establecer, documentar y hacer cumplir nuestras convenciones de API en todos los equipos. Un canal de gobernanza de API en Slack también es útil para debates animados sobre el tema.

El grupo de gobernanza identificó una serie de formas en que los cambios pueden introducirse en la API que son beneficiosos para el usuario y no constituyen un cambio importante. Estos incluyen:

  • Un nuevo recurso o punto final de API

  • Un nuevo parámetro opcional

  • Un cambio en un punto final de API no público

  • Una nueva clave opcional en el cuerpo JSON POST

  • Una nueva clave devuelta en el cuerpo de la respuesta JSON


Por el contrario, un cambio importante incluía cualquier cosa que pudiera romper la integración de un usuario, como:

  • Un nuevo parámetro requerido

  • Una nueva clave requerida en cuerpos POST

  • Eliminación de un punto final existente

  • Eliminación de un método de solicitud de punto final existente

  • Un comportamiento interno materialmente diferente de una llamada API, como un cambio en el comportamiento predeterminado.

The Big 1.0

Mientras documentábamos y discutíamos estas convenciones, también llegamos a la conclusión de que era en el mejor interés de todos (¡incluyéndonos a nosotros!) evitar realizar cambios disruptivos en la API ya que gestionar múltiples versiones añade bastante carga. Decidimos que había algunas cosas que debíamos arreglar con nuestra API antes de comprometernos con “v1”.

Enviar un correo electrónico simple requería demasiado esfuerzo.  Para “mantener las cosas simples”, actualizamos el cuerpo del POST para asegurarnos de que se acomodaran tanto los casos de uso simples como los complejos.  El nuevo formato también era más a prueba de futuro.  En segundo lugar, abordamos un problema con el endpoint de Métricas. Este endpoint usaba un parámetro “group_by” que cambiaba el formato del cuerpo de respuesta del GET de tal manera que la primera clave sería el valor del parámetro de agrupamiento. Eso no parecía muy RESTful, por lo que separamos cada agrupamiento en un endpoint diferente. Finalmente, auditamos cada endpoint e hicimos cambios menores aquí y allá para asegurar que cumplían con los estándares.

Documentación Precisa

Es importante tener documentación de API precisa y utilizable para evitar cambios disruptivos, ya sean deliberados o no intencionales. Decidimos usar un enfoque simple de documentación de API aprovechando un lenguaje Markdown llamado API Blueprint y gestionar nuestros documentos en Github. Nuestra comunidad contribuye y mejora estos documentos de código abierto.  También mantenemos un conjunto de documentos no públicos en Github para APIs y endpoints internos.

Inicialmente, publicamos nuestros documentos en Apiary, una excelente herramienta para prototipos y publicación de documentos de API. Sin embargo, integrar Apiary en nuestro sitio web no funciona en dispositivos móviles, por lo que ahora usamos Jekyll para generar documentos estáticos.  Nuestros últimos documentos de API de SparkPost ahora se cargan rápidamente y funcionan bien en dispositivos móviles, lo cual es importante para los desarrolladores que no siempre están sentados frente a su computadora.

Separando Deployment de Release

Aprendimos desde el principio el truco valioso de separar una implementación de un lanzamiento. De esta manera es posible implementar cambios con frecuencia cuando están listos a través de la entrega y despliegue continuos, pero no siempre los anunciamos o documentamos públicamente al mismo tiempo. No es raro para nosotros implementar un nuevo punto de acceso API o una mejora a un punto de acceso API existente y usarlo desde la interfaz de usuario o con herramientas internas antes de documentarlo y soportarlo públicamente. De esa manera, podemos hacer algunos ajustes para la usabilidad o conformidad con los estándares sin preocuparnos por realizar un temido cambio incompatible. Una vez que estamos satisfechos con el cambio, lo añadimos a nuestra documentación pública.

¡Doh!

Es justo admitir que ha habido ocasiones en las que no hemos cumplido nuestros ideales de «sin cambios disruptivos» y de estas vale la pena aprender. En una ocasión, decidimos que sería mejor para los usuarios si una cierta propiedad predeterminada fuese true en lugar de false. Después de implementar el cambio, recibimos varias quejas de los usuarios ya que el comportamiento había cambiado inesperadamente.  Revertimos el cambio y añadimos una configuración a nivel de cuenta – un enfoque mucho más amigable para el usuario, sin duda.

Ocasionalmente, estamos tentados a introducir cambios disruptivos como resultado de correcciones de errores. Sin embargo, decidimos dejar estas idiosincrasias solas en lugar de arriesgarse a romper las integraciones de los clientes por el bien de la consistencia.

Existen casos raros en los que tomamos la seria decisión de realizar un cambio disruptivo – como dejar obsoleto un recurso o método API – en beneficio de la mayor comunidad de usuarios y solo después de confirmar que hay poco o ningún impacto para los usuarios. Por ejemplo, tomamos deliberadamente la decisión de alterar el comportamiento de respuesta del Suppression API pero solo después de ponderar cuidadosamente los beneficios y los impactos para la comunidad y comunicar cuidadosamente el cambio a nuestros usuarios. Sin embargo,  nunca  introduciríamos un cambio que tenga una remota posibilidad de impactar directamente en el envío de un correo electrónico de producción del usuario.

Conectémosle con un experto de Bird.
Vea el poder completo del Bird en 30 minutos.

Al enviar, aceptas que Bird pueda contactarte sobre nuestros productos y servicios.

Puedes darte de baja en cualquier momento. Consulta el Aviso de Privacidad de Bird para obtener detalles sobre el procesamiento de datos.

Company

Newsletter

Mantente al día con Bird a través de actualizaciones semanales en tu buzón.

Al enviar, aceptas que Bird pueda contactarte sobre nuestros productos y servicios.

Puedes darte de baja en cualquier momento. Consulta el Aviso de Privacidad de Bird para obtener detalles sobre el procesamiento de datos.

Conectémosle con un experto de Bird.
Vea el poder completo del Bird en 30 minutos.

Al enviar, aceptas que Bird pueda contactarte sobre nuestros productos y servicios.

Puedes darte de baja en cualquier momento. Consulta el Aviso de Privacidad de Bird para obtener detalles sobre el procesamiento de datos.

Company

Newsletter

Mantente al día con Bird a través de actualizaciones semanales en tu buzón.

Al enviar, aceptas que Bird pueda contactarte sobre nuestros productos y servicios.

Puedes darte de baja en cualquier momento. Consulta el Aviso de Privacidad de Bird para obtener detalles sobre el procesamiento de datos.

Conectémosle con un experto de Bird.
Vea el poder completo del Bird en 30 minutos.

Al enviar, aceptas que Bird pueda contactarte sobre nuestros productos y servicios.

Puedes darte de baja en cualquier momento. Consulta el Aviso de Privacidad de Bird para obtener detalles sobre el procesamiento de datos.

R

Reach

G

Grow

M

Manage

A

Automate

Company

Newsletter

Mantente al día con Bird a través de actualizaciones semanales en tu buzón.

Al enviar, aceptas que Bird pueda contactarte sobre nuestros productos y servicios.

Puedes darte de baja en cualquier momento. Consulta el Aviso de Privacidad de Bird para obtener detalles sobre el procesamiento de datos.