3 puntos por GN⁺ 2024-04-27 | 1 comentarios | Compartir por WhatsApp
  • Las decisiones sobre el nombrado y modelado de recursos de API son la parte más difícil e importante del diseño de API. Los recursos forman el modelo mental del usuario sobre cómo funciona el producto y sus capacidades.
  • El equipo de Increase usa el principio de "sin abstracciones" para orientar el diseño de su API.

El enfoque de Stripe para el diseño de API

  • Una parte considerable del equipo de Increase trabajó antes en Stripe y toma en cuenta los valores detrás del exitoso diseño de API de Stripe.
  • Stripe sobresale en extraer la funcionalidad central de dominios complejos en abstracciones que los usuarios pueden entender y usar con facilidad. (Ejemplo: PaymentIntent, que abstrae las diferencias entre Visa y Mastercard)
  • La mayoría de los usuarios de Stripe son startups en etapas tempranas que desarrollan productos no relacionados con pagos, por lo que no necesitan conocer los detalles de las tarjetas de crédito. Quieren integrar Stripe rápidamente y enfocarse en construir su producto.

Los usuarios de Increase y sus principios de diseño de API

  • En cambio, los usuarios de Increase tienen un conocimiento profundo de las redes de pago, y eligieron Increase precisamente por su conexión directa a la red y la profundidad de integración.
  • Quieren saber con exactitud cuándo cierra la ventana de FedACH y en qué momento se realiza una transferencia, y entienden que configurar distintos códigos SEC en una transferencia ACH puede afectar el momento de una devolución.
  • Intentar ocultar la complejidad fundamental de estas redes no simplifica la vida de los usuarios; solo los frustra.
  • A partir de conversaciones con usuarios iniciales, derivaron el principio de "sin abstracciones" y lo aplicaron al diseño de la API.

Cómo afectó el principio de "sin abstracciones" al diseño de la API

  • Usar la terminología real: en lugar de inventar nombres propios para los recursos y atributos de la API, usan el vocabulario de la red subyacente. (Ejemplo: los parámetros de transferencias ACH usan nombres de campo de la especificación Nacha)
  • Inmutabilidad: al usar eventos reales como modelo, más recursos de API pueden ser inmutables. Resulta efectivo agrupar clústeres de recursos inmutables en "objetos de ciclo de vida" de máquina de estados. (Ejemplo: el campo status del objeto ach_transfer y varios subobjetos inmutables creados según el ciclo de vida de la transferencia)
  • Separar recursos por caso de uso: cuando el conjunto de acciones que el usuario puede tomar cambia mucho según la instancia del recurso, lo dividen en varios recursos. (Ejemplo: las transferencias ACH salientes y entrantes se separan en recursos distintos)

Cumplimiento del enfoque por parte del equipo de ingeniería

  • El equipo de ingeniería se comprometió a seguir este enfoque.
  • Al diseñar una API compleja durante años, siempre hay que tomar pequeñas decisiones incrementales; comprometerse de antemano a seguir principios base reduce la carga cognitiva de esas decisiones.
  • Por ejemplo, en el caso del campo Input Message Accountability Data requerido al enviar dinero a la Reserva Federal, en una API con mucha abstracción habría que pensar cómo renombrarlo de forma "amigable para el usuario", pero en Increase los ingenieros simplemente nombran el campo input_message_accountability_data y siguen adelante.

Opinión de GN⁺

  • El nivel de abstracción de una API puede variar según la experiencia del desarrollador con el dominio del producto y la energía que esté dispuesto a invertir en la integración. Por eso, al diseñar una API, es importante considerar el nivel de abstracción adecuado para quienes la van a integrar.
  • Si se construye una API con un alto nivel de abstracción, hay que pensar cuidadosamente antes de agregar nuevas funciones. En cambio, si se construye una API con un bajo nivel de abstracción, hay que mantener esa línea y resistir la tentación de agregar abstracciones.
  • Usar tal cual la terminología de la red o protocolo subyacente puede ayudar a los desarrolladores a entender el sistema subyacente, pero también puede convertirse en una barrera de entrada para quienes se enfrentan a él por primera vez. Por eso, parece importante contar con buenas anotaciones y documentación.
  • Usar objetos inmutables al diseñar una API puede ser efectivo para mantener la consistencia de los datos y evitar side effects. Pero, por otro lado, puede resultar incómodo cuando se necesita actualizar datos, así que hay que considerar bien ese trade-off.
  • Separar recursos por caso de uso puede aumentar la complejidad de la API, pero a largo plazo puede mejorar la predictibilidad. Aun así, si se fragmenta demasiado, la usabilidad puede verse afectada, por lo que es importante encontrar el nivel adecuado.

1 comentarios

 
GN⁺ 2024-04-27
Comentarios de Hacker News
  • Es bueno ofrecer tanto una API con abstracciones de bajo nivel como una API con abstracciones de alto nivel

    • Las API de bajo nivel permiten un control fino, pero requieren conocimiento especializado
    • Las API de alto nivel ofrecen operaciones simplificadas para casos de uso generales
    • Si se mantiene una distinción clara entre ambas API, se reduce la presión de agregar abstracciones o casos especiales a cada una
    • Es buena idea proporcionar materiales para que los clientes aprendan cómo pasar de una API a la otra
  • Me gustó la parte que explica por qué Increase eligió un enfoque distinto

    • Al diseñar algo fundamental, el contexto importa mucho, pero la gente por lo general no lo reconoce lo suficiente
  • La verdadera capacidad de Stripe es conocer a sus clientes y ofrecer la simplicidad que quieren

    • Increase también entiende bien lo que necesitan sus clientes y demuestra un enfoque similar al crear lineamientos de diseño para construir un gran producto
  • Es similar al patrón de diseño "Ubiquitous Language" del Domain-Driven Design, donde se usan en la implementación los mismos términos reales que utilizan los expertos del dominio

  • Se debe usar un lenguaje que los expertos del dominio puedan entender

    • Si el usuario conoce los archivos NACHA, usar otra terminología obliga a mantener un mapeo mental
    • En el caso de Stripe, como los usuarios no son expertos del dominio, tiene valor crear abstracciones que sean comprensibles y que al mismo tiempo oculten detalles innecesarios
  • Sin abstracciones como POSIX, las aplicaciones tendrían que escribir adaptadores para cada sistema de archivos compatible

  • Se menciona que parte de la estructura de la API se construye en una relación 1:1 con base en especificaciones controladas externamente

    • ¿Qué pasa cuando esas especificaciones evolucionan o cambian? ¿Se convierte en una API nueva?
  • Algo difícil de modelar limpiamente en una API de pagos es que los esquemas de pago representan de forma distinta los roles del pagador y del beneficiario cuando ocurre una devolución de pago

    • Por ejemplo, en ciertos esquemas el pagador y el beneficiario pueden mantenerse en las mismas posiciones que en el pago inicial
    • En cambio, en otros esquemas se invierten