arquitectura-detras-de-una-app

Una arquitectura concéntrica

Backend

Dante describe el Infierno como un embudo inmenso, dividido en círculos o trincheras llamadas “bolgias”. Cada una tiene un propósito: castigar a un tipo concreto de pecador. Cuanto más profunda la “bolgia”, más grave el pecado.

circulos-infierno-dante

En el último círculo del Infierno se hallan los peores pecadores: traidores y falsificadores. En nuestro caso, coincide con el backend, y de verdad que hasta aquí llega la analogía y para nada se trata de faltarle a nuestros amigos los desarrolladores de backend. 😉

Veamos un ejemplo concreto, como puede ser Netflix. En este caso tendríamos la gestión de usuarios y de medios. Más importante aún, aquí tenemos todo el “data science” que permite a Netflix saber qué sugerirnos según nuestros hábitos de consumo.

En las profundidades oscuras del backend es donde encontramos el modelo del producto (qué es en realidad) así como el modelo de negocio. A menudo el backend es la eminencia gris, que desde las sombras, decide el éxito o el fracaso del producto.

¿Qué sería de Whatsapp, si su backend no estuviese preparado para manejar con eficiencia millones de mensajes por segundo? En estos momentos, la tendencia es que el backend deje de ser un software monolítico y sea creado mediante microservicios.

¿Qué es un microservicio?

arquitectura-microservicios

Se trata de un software que hace una sola cosa y muy bien. Un enjambre de microservicios, comunicándose por REST, colas, etc, proporciona mayor estabilidad y escalabilidad que el modelo monolítico.

Si el microservicio que devuelve las recomendaciones se está saturando, basta con arrancar más instancias del mismo. Si por el contrario, tiene que ser actualizado, puede ser hecho sin tirar abajo todo el servidor.

La arquitectura de microservicios, que ahora hace furor en parte por el uso y evangelismo de Netflix, como casi todo en nuestra industria, es un re-inventar la rueda.

Arquitectura de servidores y arquitectura de aplicaciones

En el fondo en la arquitectura de servidores se aplican los mismos principios que en la arquitectura de aplicaciones.

En vez de tener un monolito intratable, en un caso tenemos un conjunto de microservicios. En el otro caso tenemos un conjunto de objetos o funciones que hacen una sola cosa (“single responsibility principle”) y se comunican entre sí.

Los mecanismos de comunicación son igualmente similares. HTTP & REST equivalen a métodos o funciones síncronas que pasan sus parámetros en un diccionario. Por el otro lado, las colas (RabbitMQ, Cellery, 0MQ, etc) equivalen a métodos o funciones asíncronas.

Django, RoR, Node, Go & Elixir

Con respecto a lenguajes, hoy por hoy quien está mejor establecido son Django, RoR y Node.js aunque hay nuevos competidores. Django y RoR son buenas opciones “genéricas” y son el equivalente a la navaja del ejército suizo: hacen un poco de todo y bastante bien.

navaja-suiza-multiusos

Node.js es un competidor que es especialmente adecuado para aplicaciones de tiempo real, como pueda ser un chat.

No obstante, si el backend va tener que escalar mucho y atender millones de peticiones por segundo, todas estas navajas se quedan cortas.

Go es un lenguaje creado por Google, muy sencillo y potente que cada día es más popular para backends escalables. Si los anteriores eran navajas del ejército suizo, Go es la katana de Hattori Hanzo: pocos problemas se le resisten y magnífica para matar ratas gordas.
katana-hatori-hanzo

Para casos extremos, como precisamente Whatsapp, necesitaremos una herramienta aún más potente. Aquí entran Erlang y Elixir. Si necesitas la máxima escalabilidad posible, sólo estos dos podrán sacarte las castañas del fuego. Es el sable láser: hay veces que sólo él te puede salvar.

¿Cual debemos elegir? Afortunadamente gracias a la arquitectura de microservicios no tenemos que elegir por uno u otro: podemos crear cada microservicio con la herramienta que sea más adecuada para el caso.

En estos momentos, la demanda de desarrolladores RoR parece estar decayendo, Django está estable (aunque con mejores sueldos que RoR, al menos en Europa), mientras que Node está en pleno crecimiento y Go calienta motores.

La Gran Muralla REST

En la reciente película con Matt Damon, la Gran Muralla es la barrera que separa la civilización de la barbarie. En el Infierno de Dante, existe un concepto similar: la ciudad de Dis y las murallas en llamas que separan el Infierno profundo del resto. Pasado Dis, se encuentran aquellos que han pecado a sabiendas y antes de ella, los que lo hicieron movidos por pasiones o vicios.
ciudad-de-dis

En nuestra arquitectura concéntrica, tenemos una situación similar: el backend se halla separado del resto del sistema por una API REST que oculta la complejidad del mismo y permite a los clientes comunicarse con el backend sin tener que saber detalles del mismo.

Una vez más, nos encontramos con que son conceptos familiares. En este caso, no es más que el viejo truco de la encapsulación.

En estos momentos, REST es el mecanismo por defecto para comunicarse con el otro lado de la muralla. No obstante, tiene ciertas limitaciones que se están haciendo cada vez más visibles a medida que la complejidad de los sistemas aumenta.

En estos momentos, la alternativa que está despuntando es GraphQL de Facebook. No obstante, aún son pocos los sistemas que lo usan.  Espero aprender más de GraphQL y su adopción por parte de la industria durante la conferencia de Facebook: FBF8.

Los Clientes

Antes de Dis, se encuentran alojados aquellos pecadores que no han pecado por maldad, sino que no les quedaba más remedio: glotones y lujuriosos.

En el caso de la arquitectura concéntrica, los glotones y lujuriosos seríamos los desarrolladores de clientes, tanto web como móvil.

En esta analogía, resulta difícil decidir quien sale peor parado; si el backend intrínsecamente perverso (te cambian el API y se les “olvida” avisar) o aquellos que nos hayamos tiranizados por nuestras pasiones y bajos instintos. 😉

Cliente Web

Es a menudo la primera impresión que tiene un usuario del sistema… y a veces la última. Normalmente no ofrece las mismas funcionalidades que los clientes nativos, y a menudo no es rentable. Sin embargo, generar dinero no es su función, sino generar usuarios.

Aquellos usuarios rentables, que están dispuestos a pagar por nuestro servicio, posteriormente se pasarán a algún cliente móvil o de “desktop”.

En algunos casos, en el cual el servicio en sí es incompatible con la web (como es el caso de Snapchat) ni siquiera existe un cliente web: es un enlace a la App Store y a Google Play.

Aún recuerdo una charla que tuve con los directores de desarrollo de AirBnB hace unos años en San Francisco, y me decían “si tuviésemos que empezar de nuevo la empresa hoy, no tendríamos una web app, sino tan solo un enlace a la App Store”. Esto da a entender la desproporción de los ingresos que se obtenían mediante el cliente web y los clientes móviles.

Esto no quiere decir que no sea importante, sino que su función no es la de rentabilizar usuarios, sino de atraerlos.

En este segmento, Javascript es rey. Las principales tecnologías para desarrollo de clientes web son Angular de Google y React de Facebook. React está creciendo mucho, pero Angular sigue siendo una apuesta muy segura.

Ambas son tecnologías con mucha demanda a ambas orillas del charco, aunque React es más popular en EEUU que en Europa en estos momentos.

Cliente iOS

Aquí nos encontramos con el Rey de la monetización. Si los usuarios del cliente web son eventuales y nada dispuestos a pagar, los de iOS son todo lo contrario: “heavy users” y muy dispuestos a pagar por el servicio prestado.

El terreno en iOS ha estado muy revuelto en los últimos años, con bastante inestabilidad generada por el lanzamiento de un nuevo lenguaje por parte de Apple: Swift. Swift generó un interés inusitado que probablemente haya pillado de sorpresa a la propia Apple.

Cuando fue lanzado, aún no estaba listo para ser usado en aplicaciones comerciales y a lo largo de los años sufrió innumerables cambios. Esto provocaba que tuviésemos que cambiar el código en algunos casos a cada dos semanas.

Hoy por hoy tenemos 2 opciones para desarrollar para iOS: Swift 3 y Objective C (el lenguaje estándar hasta que salió Swift). Aquél que quiera especializarse en desarrollo iOS tiene que conocer ambos.

Esta complejidad extra ha hecho que ciertas alternativas, como React Native, hayan cobrado fuerza. En parte por la promesa de generar clientes nativos para iOS & Android a partir de un mismo código fuente Javascript, por el apoyo de un gigante como Facebook y también por la inseguridad que hemos vivido con las versiones 1 y 2 de Swift.

Sin embargo, en el segmento de desarrollo de clientes nativos, iOS “sigue siendo el Rey” y es una de las habilidades más demandadas por el mercado.

Cliente Android

Android ocupa un puesto intermedio entre el cliente web y el cliente iOS. Sus usuarios no suelen ser tan leales como los de iOS ni tan rentables, pero sí que son más rentables que los del cliente web.

Al contrario de iOS, que ha estado demasiado agitado, el mundo de Android está tal vez demasiado estable. Se sigue usando Java para el desarrollo, y aunque se habla de posibles nuevos lenguajes y herramientas de momento Google da la callada por respuesta.

No obstante, Google tiene algunos problemas legales con la licencia de Android que no hace que sea descabellado pensar en un cambio radical en un futuro.

Aunque hay más desarrolladores Android que iOS, en general es más difícil encontrar verdaderos expertos en Android que en iOS. Quien domina ambos lados de la Fuerza, tiene un gran valor de mercado.

La importancia de la visión de conjunto

Dicen que cuando se estaban construyendo las pirámides de Egipto, un anciano se acercó a la obra. Le preguntó a uno de los obreros qué estaba haciendo.

—Es evidente que estoy poniendo ladrillos —contestó sin prestarle mucha atención.

No satisfecho con esa respuesta, le preguntó a otro lo mismo.

—Estoy construyendo una pared —le dijo. En ese momento, vió que el primero había puesto mal un ladrillo y que éste iba a sobresalir de la pared. De inmediato se enzarzó en una discusión con el primero.

Aún no satisfecho, le preguntó a un tercer hombre lo que estaban haciendo. Éste, que resultó ser el arquitecto, le contestó: «Estamos creando un monumento tan espectacular, que dentro de 4 mil años, los hombres aún lo mirarán con admiración y asombro». En ese momento se percató de la discusión de los otros dos, y les explicó que la pared que estaban haciendo era interior y nadie iba a ver ese ladrillo sobresaliente. No tenía sentido perder más tiempo con él.

Esto deja claro la importancia de tener una visión de conjunto de lo que estamos creando. Es vital, no sólo para nuestra capacidad como profesionales, sino también para nuestra seguridad. Un desarrollador que tiene clara la estructura concéntrica, los papeles de cada componente y las tecnologías que se usan, aportará más valor a la empresa y podrá adaptarse mejor a los cambios, al verlos venir de lejos. Y es esta estructura la que inspira del principio al fin nuestro Mobile Startup Engineering Bootcamp.

KeepCoding Team

Acerca de KeepCoding Team

Aquí nos encontramos todo el Equipo que forma KeepCoding Team que a diario colaboramos y damos soporte a todos los Geeks Inivitados para que sus maravillosos artículos salgan a la luz con el mejor formato.

Share this:

10 comments, add yours.

Carlos

Cuando dices que nodejs “No obstante, si el backend va tener que escalar mucho y atender millones de peticiones por segundo, todas estas navajas se quedan cortas.”, creo que no es así ya que empresas como PayPal utilizan node y a mi no me parece una empresa la cual realice pocas peticiones diarias.

    Fernando Rodriguez

    Fernando Rodriguez

    Paypal y Whatsapp (el ejemplo que creo recordar haber puesto) están en distintas ligas con respecto a transacciones por segundo. Para cada cosa su herramienta.

Jorge Ledezma

Hola Fernando! Qué bueno que has vuelto a escribir.

Ya en varios proyectos he querido implementar una arquitectura con microservicios pero acabo perdido en mi propio infierno cuando veo la cantidad de joins de tablas que requiere mi modelo. Me acostumbré a ser muy relacional en eso de dividir una base de datos en muchísimas tablas y a la hora de pasar todo a modelos separados siento que las soluciones bajan el desempeño o me obligan a optar redundar y sincronizar lo que no me parece elegante. Cómo resuelves esto?

    Fernando Rodriguez

    Fernando Rodriguez

    Hola Jorge! Qué bueno volver a saber de ti. Ahora estamos más cerca! 😉

    Habría que ver el caso concreto, pero el tener que desnormalizar a mi también me repatea el hígado. ¿Qué tal si lo planteamos en el próximo webinar de micro-servicios?

      Jesús Perales

      Concuerdo con eso, la normailzación es algo que quieras que no ayuda a evitar muchos posibles errores, como desnormalizar sin morir en el intento.

Miguel A. Gómez

Gran entrada, es estupendo tenerte de vuelta Fernando! Se echaban de menos los posts de cocoa mental!

    Fernando Rodriguez

    Fernando Rodriguez

    Hola Miguel, ¡muchas gracias! A mí tambien me sienta bien estar de vuelta. La cabra tira al monte, y ya era hora. 😉

David Céspedes

Una actualización rápida de lo que como desarrolladores deberíamos conocer por lo menos, así no lo manejemos. Tengo varios temas pendientes. Muy interesante la pregunta de Jorge Ledezma (Saludos!) por que me pasó lo mismo. Trate de empezar a despedazar el backend de mi Startup en micro-servicios, pero acababa replicando el modelo para poder usarlo en cada micro-servicio, o mi base de datos iba a ser un cuello de botella en poco tiempo.

    Fernando Rodriguez

    Fernando Rodriguez

    En estos casos no toca más de usar varias BDs y sí que es un poco rollo. Vamos a verlo en el próximo webinar!

Rafa G. Blanes

Gracias por el artículo, me encanta el concepto de arquitectura “concéntrica”, muy visual y acertado.

Leave a comment