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 sabe cualquiera que haya construido o utilice regularmente una API, tarde o temprano se da cuenta, los cambios disruptivos son muy malos y pueden ser una mancha muy seria en una API que de otro modo sería útil. Un cambio disruptivo 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 disruptivos requieren que los usuarios sean notificados con anticipación (con las correspondientes disculpas) en lugar de un cambio que simplemente aparece, como una nueva y encantadora característica. La forma 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 es difícil es mantener algo de cordura al no degradarse innecesariamente en un mareo de versiones y subversiones aplicadas a través de docenas de puntos de acceso de API con compatibilidades poco claras.




Introdujimos la v1 de la API hace tres años y no nos dimos cuenta de que seguiría siendo 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 pero mantenemos la misma versión de API? Mientras que 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 del versionado de APIs.

REST Es Mejor

El 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 actualización importante a la versión 3.x, nuestro MTA líder en el mercado en las instalaciones. Momentum 4 incluía una nueva interfaz de usuario, analíticas en tiempo real y, lo más importante, un nuevo API web para la inyección y generación de mensajes, gestionar plantillas y obtener métricas de correo electrónico. Nuestra visión era una arquitectura en la que el API fuera primero, donde incluso la interfaz de usuario interactuaría con los endpoints del API.




Una de las mejores y más tempranas decisiones que tomamos fue adoptar un estilo RESTful. Desde finales de los 2000, las APIs web basadas en transferencia de estado representacional (REST) son el estándar de facto de las APIs en la nube. Usar HTTP y JSON facilita a los desarrolladores, sin importar qué lenguaje de programación usen - PHP, Ruby y Java - integrar con nuestro API sin conocer o preocuparse por nuestra tecnología subyacente.




Elegir usar la arquitectura RESTful fue fácil. Elegir una convención de versionado no fue tan sencillo. Inicialmente dejamos de lado 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 construir nuestro servicio en la nube. Tiempo de versionado. Evaluamos dos convenciones de versionado. La primera era poner el versionado directamente en el URI y la segunda era usar una cabecera 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, era la elección lógica.

El 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 actualización importante a la versión 3.x, nuestro MTA líder en el mercado en las instalaciones. Momentum 4 incluía una nueva interfaz de usuario, analíticas en tiempo real y, lo más importante, un nuevo API web para la inyección y generación de mensajes, gestionar plantillas y obtener métricas de correo electrónico. Nuestra visión era una arquitectura en la que el API fuera primero, donde incluso la interfaz de usuario interactuaría con los endpoints del API.




Una de las mejores y más tempranas decisiones que tomamos fue adoptar un estilo RESTful. Desde finales de los 2000, las APIs web basadas en transferencia de estado representacional (REST) son el estándar de facto de las APIs en la nube. Usar HTTP y JSON facilita a los desarrolladores, sin importar qué lenguaje de programación usen - PHP, Ruby y Java - integrar con nuestro API sin conocer o preocuparse por nuestra tecnología subyacente.




Elegir usar la arquitectura RESTful fue fácil. Elegir una convención de versionado no fue tan sencillo. Inicialmente dejamos de lado 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 construir nuestro servicio en la nube. Tiempo de versionado. Evaluamos dos convenciones de versionado. La primera era poner el versionado directamente en el URI y la segunda era usar una cabecera 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, era la elección lógica.

El 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 actualización importante a la versión 3.x, nuestro MTA líder en el mercado en las instalaciones. Momentum 4 incluía una nueva interfaz de usuario, analíticas en tiempo real y, lo más importante, un nuevo API web para la inyección y generación de mensajes, gestionar plantillas y obtener métricas de correo electrónico. Nuestra visión era una arquitectura en la que el API fuera primero, donde incluso la interfaz de usuario interactuaría con los endpoints del API.




Una de las mejores y más tempranas decisiones que tomamos fue adoptar un estilo RESTful. Desde finales de los 2000, las APIs web basadas en transferencia de estado representacional (REST) son el estándar de facto de las APIs en la nube. Usar HTTP y JSON facilita a los desarrolladores, sin importar qué lenguaje de programación usen - PHP, Ruby y Java - integrar con nuestro API sin conocer o preocuparse por nuestra tecnología subyacente.




Elegir usar la arquitectura RESTful fue fácil. Elegir una convención de versionado no fue tan sencillo. Inicialmente dejamos de lado 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 construir nuestro servicio en la nube. Tiempo de versionado. Evaluamos dos convenciones de versionado. La primera era poner el versionado directamente en el URI y la segunda era usar una cabecera 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, era 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?  ¿Reversionaríamos toda la API o solo ciertos endpoints? En SparkPost, tenemos varios equipos trabajando en diferentes partes de nuestra API. Dentro de esos equipos, las personas trabajan en diferentes endpoints 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 la versión.




Establecimos un grupo de gobernanza que incluye ingenieros que representan a cada equipo, un miembro del equipo de gestión de producto 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 resulta útil para debates animados sobre el tema.




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




  • Un nuevo recurso o endpoint de API

  • Un nuevo parámetro opcional

  • Un cambio en un endpoint de API no público

  • Una nueva clave opcional en el cuerpo POST de JSON

  • Una nueva clave devuelta en el cuerpo de respuesta JSON




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




  • Un nuevo parámetro requerido

  • Una nueva clave requerida en cuerpos POST

  • Eliminación de un endpoint existente

  • Eliminación de un método de solicitud de endpoint 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 (¡incluidos nosotros!) evitar hacer cambios que rompieran el API, ya que gestionar múltiples versiones agrega bastante carga. Decidimos que había algunas cosas que debíamos corregir con nuestro 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 asegurar que tanto los casos de uso simples como los complejos estén acomodados.  El nuevo formato también era más a prueba de futuro.  En segundo lugar, abordamos un problema con el endpoint de Metrics. Este endpoint utilizaba un parámetro “group_by” que cambiaría el formato del cuerpo de respuesta GET de tal manera que la primera clave sería el valor del parámetro group by. Eso no parecía muy RESTful, así que dividimos cada group by en un endpoint separado. Finalmente, auditamos cada endpoint e hicimos cambios menores aquí y allá para asegurar que se conformaran 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. 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 internas y puntos de conexión.




Inicialmente, publicamos nuestros documentos en Apiary, una excelente herramienta para prototipar y publicar documentación de API. Sin embargo, incrustar Apiary en nuestro sitio web no funciona en dispositivos móviles, por lo que ahora usamos Jekyll para generar documentos estáticos.  Nuestros últimos SparkPost API docs ahora cargan rápidamente y funcionan bien en dispositivos móviles, lo cual es importante para los desarrolladores que no siempre están sentados en 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 estado a la altura de nuestros ideales de "sin cambios disruptivos" y vale la pena aprender de ellos. En una ocasión, decidimos que sería mejor para los usuarios si una cierta propiedad tuviera el valor predeterminado verdadero en lugar de falso. Después de implementar el cambio, recibimos varias quejas de 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, nos sentimos tentados a introducir cambios disruptivos como resultado de correcciones de errores. Sin embargo, decidimos dejar estas idiosincrasias como están en lugar de arriesgar las integraciones de los clientes por el bien de la consistencia.




Hay casos raros en los que tomamos la seria decisión de hacer un cambio disruptivo, como desaprobar un recurso o método de API en interés de la comunidad de usuarios y solo después de confirmar que hay poco o ningún impacto para los usuarios. Por ejemplo, deliberadamente tomamos la decisión de alterar el comportamiento de respuesta del Suppression API, pero solo después de sopesar 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 tuviera una posibilidad remota de impactar directamente el envío de un correo electrónico de producción de un usuario.

Únete a nuestro 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.

Únete a nuestro 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.

Únete a nuestro 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.

Pinterest logo
Uber logo
Square logo
Logo de Adobe
Meta logo
PayPal logo

Company

Configuración de privacidad

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.

Uber logo
Square logo
Logo de Adobe
Meta logo

Company

Configuración de privacidad

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.

Uber logo
Logo de Adobe
Meta logo

Reach

Grow

Manage

Automate

Recursos

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.