Translate

martes, 8 de agosto de 2017

Nuevo centro de contenido de MongoDB

Me llego el siguiente mail, y quería compartirlo con ustedes:

Visite nuestro nuevo centro de contenido 

Hola, 

Visite nuestro centro de contenido para ver todas las novedades sobre MongoDB, NoSQL y últimas tendencias en programación. 

En nuestro centro de contenido podrá encontrar información sobre los siguientes temas:
  • Casos de cliente, productos y arquitectura de MongoDB
  • Big Data
  • Internet of Things
  • Análisis en tiempo real con Apache Spark

Visitar el centro

En nuestro centro de contenido tiene a su disposición vídeos, artículos y libros, todo en un mismo lugar. 

Reciba un cordial saludo,

El equipo de MongoDB
 
 Share on TwitterShare on FacebookShare on LinkedInShare on Google+ 
 
MongoDB Inc., 2017. Todos los derechos reservados.
Palacio de Miraflores, Suite 219 & 220, Carrera de San Jerónimo 15 - 2, Madrid 28014, Spain

Para darse de baja de futuros mensajes de MongoDB o para actualizar sus preferencias de correo electrónico haga clic aquí.
 

domingo, 6 de agosto de 2017

Un resumen de Scala for the Impatient, parte 28

Expresiones Regulares

Cuando tomamos un texto como entrada podemos utilizar expresiones regulares para analizarlos. La clase scala.util.matching.Regex nos puede facilitar las cosas, para construir este objeto, se puede utilizar el método r de la clase String:

val numPattern = "[0-9]+".r

Si la expresión regular contiene barras invertidas o comillas, entonces es una buena idea usar la sintaxis de cadena "raw", "" "..." "". Por ejemplo:

val wsnumwsPattern = """\s+[0-9]+\s+""".r
// A bit easier to read than "\\s+[0-9]+\\s+".r

El metodo findAllIn retorna un iterador que itera por todas las coincidencias. Y esto se puede utilizar en un for :

for (matchString <- numPattern.findAllIn("99 bottles, 98 bottles"))
   process matchString

O podemos retornar un arreglo con toArray :

val matches = numPattern.findAllIn("99 bottles, 98 bottles").toArray
// Array(99, 98)

Si buscamos solo el primer elemento que coincida, podemos utilizar el método findFirstIn. Que retorna un Option[String]

val m1 = wsnumwsPattern.findFirstIn("99 bottles, 98 bottles")
// Some(" 98 ")

Para comprobar si el principio de una cadena coincide, utilice findPrefixOf:

numPattern.findPrefixOf("99 bottles, 98 bottles")
// Some(99)
wsnumwsPattern.findPrefixOf("99 bottles, 98 bottles")
// None

Si se desea remplazar la primera coincidencia o todas las coincidencias:

numPattern.replaceFirstIn("99 bottles, 98 bottles", "XX")
// "XX bottles, 98 bottles"
numPattern.replaceAllIn("99 bottles, 98 bottles", "XX")
// "XX bottles, XX bottles"

Grupos de expresiones regulares.

Los grupos son útiles para obtener subexpresiones de expresiones regulares. Añada paréntesis alrededor de las subexpresiones que desea extraer, por ejemplo:

val numitemPattern = "([0-9]+) ([a-z]+)".r

Para hacer coincidir los grupos, utilice el objeto de expresión regular como un "extractor":

val numitemPattern(num, item) = "99 bottles"
// Sets num to "99", item to "bottles"

Si desea extraer grupos de coincidencias múltiples, utilice una instrucción for de este modo:

for (numitemPattern(num, item) <- numitemPattern.findAllIn("99 bottles, 98 bottles"))
    process num and item

Un resumen de Scala for the Impatient, parte 27



Revisar un directorios.

No existe una clase oficial para revisar directorios en carpetas pero vamos a ver algunas alternativas.

Es muy simple escribir una función que recorra todas las carpetas y subcarpetas:

import java.io.File
def subdirs(dir: File): Iterator[File] = {
    val children = dir.listFiles.filter(_.isDirectory)
    children.toIterator ++ children.toIterator.flatMap(subdirs _)
}

Con esta función se puede visitar todos los subdirectorios:

for (d <- subdirs(dir)) process d

Si utilizamos Java 7, se puede utilizar el metodo walkFileTree de la clase java.nio.file.Files. Esta clase hace uso de la interfaz FileVisitor. En scala se prefiere utilizar funciones de objetos y no interfaces. Por lo tanto podemos adaptar esta funcionalidad a una visión más scala:

import java.nio.file._
implicit def makeFileVisitor(f: (Path) => Unit) = new SimpleFileVisitor[Path] {
    override def visitFile(p: Path, attrs: attribute.BasicFileAttributes) = {
        f(p)
        FileVisitResult.CONTINUE
    }
}

Por lo tanto se pueden imprimir todos los directorios de esta manera:

Files.walkFileTree(dir.toPath, (f: Path) => println(f))

Si se quiere realizar otra acción, se pasara otro método y no println

Serialización. 

Esto no tiene ninguna relación con los cereales (jeje). En Java, la serialización es utilizada para cuando queremos transmitir un objeto a otra maquina virtual o para guardar el objeto por un tiempo mínimo.

En scala se puede utilizar el mismo mecanismo pero su declaración es un tanto diferente:

Java:
public class Person implements java.io.Serializable {
    private static final long serialVersionUID = 42L;
    …
}

Scala:
@SerialVersionUID(42L) class Person extends Serializable

El Trait Serializable esta definido en el paquete scala por lo que no es necesario ningún import.
Si nos olvidamos de @SerialVersionUID este tomara un valor por defecto.

Serializar y desserializar un objeto es similar a Java:

val fred = new Person(...)
import java.io._
val out = new ObjectOutputStream(new FileOutputStream("/tmp/test.obj"))
out.writeObject(fred)
out.close()
val in = new ObjectInputStream(new FileInputStream("/tmp/test.obj"))
val savedFred = in.readObject().asInstanceOf[Person]

En scala las colecciones son seriabilizables por lo que se pueden utilizar como atributos de objetos seriabilizables:

class Person extends Serializable {
    private val friends = new ArrayBuffer[Person] // OK—ArrayBuffer is serializable
    …
}

Procesos de control

Tradicionalmente los administradores de sistema utilizan un script de shell para hacer tareas de mantenimiento como mover archivos o combinarlos. Los lenguajes script hacen fáciles estas tareas pero como lenguajes de programación dejan mucho que desear.

Scala fue diseñado para poder hacer desde humildes script a grandes aplicaciones. El paquete scala.sys.process provee utilidades para interactuar con programas shell. Es decir que podemos escribir programas tipo shell con scala.

Veamos un ejemplo simple:

import sys.process._
"ls -al .." !

Como resultado obtendremos el listado de todos los archivos del directorio. sys.process tiene un convertidor implícito de string al objeto ProcessBuilder. Y con el operador ! ejecutamos el comando.

El resultado del operador ! es un numero entero que si es 0 el comando tuvo éxito y si es distinto de 0, no.

Si utilizamos el operador !! esto retornara un string :

val result = "ls -al .." !!

Se puede utilizar este resultado como entrada de otros programas con el operador |# que es similar al operador | de linux:

"ls -al .." #| "grep sec" !

Se puede redireccionar la salida con el operador #>

"ls -al .." #> new File("output.txt") !

Si se desea que se agregar en el archivo se puede utilizar #>>

"ls -al .." #>> new File("output.txt") !

Y si se desea introducir una estrada se debe utilizar #<

"grep sec" #< new File("output.txt") !

Se puede introducir un input desde una URL :

"grep Scala" #< new URL("http://horstmann.com/index.html") !
 
Notemos que los operadores de scala se diferencian de los operadores bash solo porque comienzan con el carácter #.

sábado, 5 de agosto de 2017

Java y C caen en popularidad según el indice Tiobe

Bueno, yo la vi venir, los grandes ganadores en el indice Tiobe de los últimos años han bajado. Java y C han bajado bastante no para dejar el podio pero ha sido una gran sacudida, dado que venían estables o creciendo.

Si bien no soy capaz de opinar sobre C, me atrevo a opinar de Java y creo que la principal razón de su caída son :

  • Los nuevos lenguajes que tiene la plataforma, como Kotlin, Scala, Groovy, Clojure y etc. Recordemos que ahora Kotlin es un lenguaje oficial para android. 
  • La plataforma .net esta ganando un lugar en el open source con .net core

Pero esta es solo mi opinión, veamos los números de agosto:


  • Java (12.961%)
  • C (6.477%)
  • C++ (5.55%)
  • C# (4.195%)
  • Python (3.692%)
  • Visual Basic .Net (2.569%)
  • PHP (2.293%)
  • JavaScript (2.098%)
  • Perl (1.995%)
  • Ruby (1.965%)
Claramente no se ve mucho la evolución pero en este gráfico queda super claro: 



Lo extraño es que no hay un claro ganador, es como que se diversifico. Sera el fin de Java? Que piensan?

Dejo link:
https://www.tiobe.com/tiobe-index/
http://www.infoworld.com/article/3212970/application-development/java-and-c-hit-all-time-lows-in-tiobe-language-popularity-index.html

jueves, 3 de agosto de 2017

Donar

Agregue al Blog un botón para que puedan hacer donaciones al mismo, la idea es que con esas donaciones pueda comprar libros, hacer cursos y por supuesto que esto quede reflejado en el blog.

Si piensas que esto debe o puede mejorar o estas conforme pero quiere ir por más, dona unas divisas para poder seguir mejorando.

Saludos y gracias!!

martes, 1 de agosto de 2017

Un resumen de Scala for the Impatient, parte 26



Leer una linea de archivo

Leer todas lineas desde un archivo, puede llamar al método getLine del Objeto scala.io.Source :

import scala.io.Source
val source = Source.fromFile("myfile.txt", "UTF-8")
// El primer argumento va ser un string or java.io.File
val lineIterator = source.getLines

El resultado es un iteraror que permite procesar las lineas:

for (l <- lineIterator) process l

o se puede volcar las lineas en un arreglo o en un buffer :

val lines = source.getLines.toArray

Algunas veces deseamos volcar el contenido de un archivo en un string, lo podemos hacer con :

val contents = source.mkString

Ojo! Cuando terminamos de usar source debemos cerrarlo.

Para leer caracteres podemos utilizar directamente source e iterar por le mismo:

for (c <- source) process c

Si deseamos leer un archivo (como istream :: peek en C ++ o PushbackInputStreamReader en Java), llama al método buffered en el origen

val source = Source.fromFile("myfile.txt", "UTF-8")
val iter = source.buffered
while (iter.hasNext) {
    if (iter.head is nice)
        process iter.next
    else
        …
}
source.close()

Veamos como podemos leer un todos lo espacios en nuestro código:

val tokens = source.mkString.split("\\s+")

Para convertir un String a entero o flotante se puede utilizar los métodos toInt o toDouble

Si necesitamos leer un entero desde la consola, podemos hacer lo siguiente:

print("Cuntos años tienes? ")
val age = readInt()
// O podemos usar readDouble o readLong

Este comando asume que el usuario ingresará un numero y si no lo hace se lanzara NumberFormatException

Leer url o otros recursos. 

Para leer desde una Url o algun otro recurso podemos utilizar Source de la siguiente manera:

val source1 = Source.fromURL("http://horstmann.com", "UTF-8")
val source2 = Source.fromString("Hello, World!")
// lee desde un string, puede ser util para cuando se esta debugeando
val source3 = Source.stdin
// lee desde la entrada estandar

Leer archivos Binarios. 

Para leer archivos binarios debemos utilizar la librería estándar de java. Veamos como podemos leer un archivo binario a un array de bytes:

val file = new File(filename)
val in = new FileInputStream(file)
val bytes = new Array[Byte](file.length.toInt)
in.read(bytes)
in.close()

Escribir un archivo de texto. 

Scala no tiene un objeto o función especial para escribir archivos, debemos utilizar la librería de java. Por ejemplo:

val out = new PrintWriter("numbers.txt")
for (i <- 1 to 100) out.println(i)
out.close()

Todo funciona como se esperaba, excepto para el método printf. Cuando pasa un número a printf, el compilador se quejará de que necesita convertirlo a un AnyRef:

out.printf("%6d %10.2f",
 quantity.asInstanceOf[AnyRef], price.asInstanceOf[AnyRef])

pero podemos usar el método de formato de la clase String:

out.print("%6d %10.2f".format(quantity, price))

jueves, 27 de julio de 2017

Deploying Reactive Microservices



Quiero compartir el siguiente ebook, dado que es muy interesante el tema de los deploy en una arquitectura multiservicio. La verdad es que no tengo claro como hacerlo de forma practica y al parecer este libro te lo cuenta.

Dejo link:
http://post.oreilly.com/rd/9z1z9nleet9l259ived56o2srkjieg5gquk49qomong

miércoles, 26 de julio de 2017

Try laravel

Es genial tener muchos cursos tipo try de codeschool, ahora presentan un curso de laravel que para ser honesto era un framework php que no conocia.

Si más dejo la info:


  1. Try Laravel Level 1 Badge

    Level 1 Free Level 2 Videos | 8 Challenges
    Welcome to Laravel

    Get a quick overview of Laravel and learn about CRUD actions.
  2. Try Laravel Level 2 Badge

    Level 2 Free Level 2 Videos | 7 Challenges
    Models & Views

    Learn how to get and display data from the database using models and views.
  3. Try Laravel Level 3 Badge

    Level 3 Free Level 2 Videos | 7 Challenges
    Controllers & Routing

    Explore how controllers manage the heavy lifting with logic and how routing helps direct the traffic of our application.
Try Laravel
Complete these levels to unlock

Course Completion Badge

Dig into an overview of the Laravel framework and learn how to start building PHP applications with MVC architecture.



Dejo link: http://campus.codeschool.com/courses/try-laravel/

lunes, 24 de julio de 2017

Un resumen de Scala for the Impatient, parte 25

La herencia de jerarquías en Scala.

El siguiente gráfico muestra la jerarquía de clases en Scala. Los tipos primitivos de java extienden de AnyVal.

Las referencias a clases o subclases extienden de AnyRef, que es sinónimo de Object de java o .net.
AnyVal y AnyRef extienden de Any, el inicio de la jerarquía.

La clase Any define los métodos isInstanceOf, asInstanceOf y métodos generales como equals o hashcode.

AnyVal no agrega ningún método, solo representa el tipo de los valores.

AnyRef agrega métodos de monitoreo como wait, notify o notifyAll (que son métodos de la clase Object) , también tiene un método synchronized, el cual puede recibir como parámetro una clausura, la cual va ser ejecutada como threed safe.

Todas las clases de scala implementan la interface ScalaObject, que no tiene métodos.

En el otro extremo de la jerarquía están los tipos Nothing y Null. Null es un tipo que tiene una sola instancia null, el desarrollador puede asignar null a cualquier referencia pero no a cualquier valor. Por ejemplo no se le puede asignar null a un valor entero.

El tipo Nothing no tiene instancia, ocasionalmente es útil para constructores genéricos o por ejemplo para definir Nil (que en una lista vacía) de tipo List[Nothing]

Ojo Nothing no es igual que void de Java o C, void en scala se representa con el tipo Unit, que es un tipo que tiene un solo valor ().  Tenga en cuenta que Unit no es un supertipo de ningún otro tipo. Sin embargo, el compilador permite que Any sea reemplazado por Unit.

Igualdad de objetos

En scala, el método eq esta definido en la clase AnyRef y comprueba si dos referencias referencian al mismo objeto. El método equals en AnyRef llama eq. Cuando implemente una clase, debe considerar la posibilidad sobrescribir el método equals para proporcionar una noción natural de igualdad para los objetos.
 
Por ejemplo, si definimos class Item(val description: String, val price: Double) se debe sobrescribir el método equals como en Java:

final override def equals(other: Any) = {
val that = other.asInstanceOf[Item]
if (that == null) false
else description == that.description && price == that.price
}

Cuando defina iguales, recuerde definir también hashCode como en Java. El código de hash se debe calcular sólo a partir de los campos que se utilizan en la comprobación de igualdad. Por ejemplo:

final override def hashCode = 13 * description.hashCode + 17 * price.hashCode

Generalmente no se llama el método eq o equals. Simplemente utilice el operador ==. Para tipos de referencia, llama a equals después de hacer la comprobación adecuada para los operandos nulos.



Curso gratuitos online!!

Quiero compartir estos cursos gratuitos online, que a simple vista estan muy buenos: 
cursos diplomados 

Diplomado Tecnico Big Data 

Diplomados gratuitos online con certificado 

Diplomado Tecnico en Sistemas Informaticos 


cursos online 

Diplomado Técnico en Integridad Web 


administracion 

Gestion de Ambientes Virtuales de Aprendizaje 


finanzas 

Desarrollo de Estrategias Digitales de Aprendizaje 


cursos diplomados 

Desarrollo de sitios web y aplicaciones moviles 

domingo, 23 de julio de 2017

Introducción a la programación en Python I: Aprendiendo a programar con Python


Encontré este curso sobre python, y a simple vista esta bueno, esta dictado por la universidad Pontificia Universidad Católica de Chile y es gratuita y esta en castellano.

Dejo link: https://www.coursera.org/learn/aprendiendo-programar-python

jueves, 20 de julio de 2017

Functional Programming in Haskell: Supercharge Your Coding



Me encontré con este curso en futureLearn y ya me anote. Es un curso introductorio a Haskell, el lenguaje de programación funcional cada vez más popular y es un curso de la Universidad de Glasgow.

Comienza el 18 de septiembre del 2017 y es gratuito pero hay que pagar para aceder a la certificación.

Dejo link: https://www.futurelearn.com/courses/functional-programming-haskell

lunes, 17 de julio de 2017

El patrón de arquitectura space-based


El patrón de arquitectura space-based (también llamado a veces patrón de la arquitectura de la nube) minimiza los factores que limitan el escalamiento de la aplicación. Este patrón obtiene su nombre del concepto de espacio de tupla, la idea de memoria compartida distribuida. La alta escalabilidad se logra eliminando la restricción de la base de datos central y utilizando replicas en un grid de datos de memoria. Los datos de la aplicación se guardan en la memoria y se replican entre todas las unidades de proceso activas. Las unidades de procesamiento pueden arrancarse y apagarse dinámicamente a medida que aumenta y disminuye la carga del usuario, con lo que se aborda la escalabilidad variable. Debido a que no existe una base de datos central, el cuello de botella de la base de datos se elimina, proporcionando escalabilidad casi infinita dentro de la aplicación.

La mayoría de las aplicaciones que se ajustan a este patrón son sitios web estándar que reciben una solicitud de un navegador y realizan algún tipo de acción. Un sitio de subastas de licitación es un buen ejemplo de esto. El sitio recibe continuamente ofertas de los usuarios de Internet a través de una solicitud de navegador. La aplicación recibirá una puja por un elemento en particular, registrará esa puja con una marca de tiempo y actualizará la última información de puja para el elemento y enviará la información al navegador.

El componente de la unidad de procesamiento contiene los componentes de la aplicación (o partes de los componentes de la aplicación). Esto incluye componentes basados en web, así como lógica de negocio de back-end. El contenido de la unidad de procesamiento varía en función del tipo de aplicación: las aplicaciones basadas en web más pequeñas probablemente se desplegarán en una sola unidad de procesamiento, mientras que las aplicaciones más grandes pueden dividir la funcionalidad de la aplicación en múltiples unidades de procesamiento basadas en las áreas funcionales de la aplicación. La unidad de procesamiento contiene típicamente los módulos de aplicación, junto con un grid de datos en memoria y un almacén persistente asíncrono opcional para salvar errores. También contiene un motor de replicación que es utilizado por el middleware virtualizado para replicar los cambios de datos realizados por una unidad de procesamiento a otras unidades de procesamiento activas.

El middleware virtualizado es esencialmente el controlador de la arquitectura y administra solicitudes, sesiones, replicación de datos, procesamiento de solicitud distribuida y despliegue de unidades de proceso. Hay cuatro componentes de arquitectura principales en el middleware virtualizado: grid de mensajería, grid de datos, grid de procesamiento y el gestor de despliegue.

Grid de mensajería, administra la solicitud de entrada y la información de la sesión. Cuando una solicitud llega al componente middleware virtualizado, el grid de mensajería determina qué componentes activos de procesamiento están disponibles para recibir la solicitud y reenvía la solicitud a una de esas unidades de procesamiento. La complejidad de grid de mensajería puede ir desde un simple algoritmo round-robin hasta un algoritmo más complejos.

Grid de datos es quizás el componente más importante y crucial en este patrón. Grid de datos interactúa con el motor de replicación de datos en cada unidad de procesamiento para gestionar la replicación de datos entre unidades de procesamiento cuando se producen actualizaciones de datos. Puesto que Grid de mensajería puede enviar una solicitud a cualquiera de las unidades de procesamiento disponibles, es esencial que cada unidad de procesamiento contenga exactamente los mismos datos en su grid de datos en memoria. La replicación de datos síncrona entre unidades de procesamiento, se hace en paralelo asincrónicamente y muy rápidamente, a veces completando la sincronización de datos en cuestión de microsegundos (una millonésima de segundo).

Grid de procesamiento es un componente opcional dentro del middleware virtualizado que gestiona el procesamiento de solicitud distribuida cuando hay varias unidades de procesamiento, cada una de las cuales maneja una parte de la aplicación. Si entra una petición que requiere coordinación entre los tipos de unidades de procesamiento (por ejemplo, una unidad de procesamiento de pedidos y una unidad de procesamiento de clientes), es grid de procesamiento la que media y ordena la solicitud entre esas dos unidades de procesamiento.

El componente de gestor de despliegue gestiona el arranque dinámico y el apagado de las unidades de procesamiento en función de las condiciones de carga. Este componente monitorea continuamente los tiempos de respuesta y las cargas del usuario, e inicia nuevas unidades de procesamiento cuando aumenta la carga, y cierra las unidades de procesamiento cuando la carga disminuye. Es un componente crítico para lograr las necesidades de escalabilidad variable dentro de una aplicación.


El modelo de arquitectura space-based es un patrón complejo y costoso de implementar. Es una buena opción de arquitectura para aplicaciones web más pequeñas con carga variable (por ejemplo, sitios de medios sociales, sitios de pujas y subastas). Sin embargo, no es adecuado para aplicaciones de bases de datos relacionales de gran escala tradicionales con grandes cantidades de datos operativos.

Dejo link; https://www.oreilly.com/ideas/software-architecture-patterns/page/6/space-based-architecture

El patrón de arquitectura microservicios

El patrón de arquitectura microservicios está ganando rápidamente terreno en la industria como una alternativa viable a las aplicaciones monolíticas y arquitecturas orientadas al servicio. Debido a que este patrón de arquitectura sigue evolucionando, hay mucha confusión en la industria acerca de lo que es este patrón y cómo se implementa. 

Independientemente de la topología o el estilo de implementación elegidos, hay varios conceptos básicos comunes que se aplican al patrón de arquitectura general. El primero de estos conceptos es la noción de unidades desplegadas separadamente. Cada componente de la arquitectura de microservicios se despliega como una unidad separada, permitiendo un despliegue más fácil a través de una tubería de entrega efectiva y simplificada, mayor escalabilidad y un alto grado de aplicación y desacoplamiento de componentes dentro de su aplicación.

Quizás el concepto más importante para entender con este patrón es la noción de un componente de servicio. En lugar de pensar en los servicios dentro de una arquitectura de microservicios, es mejor pensar en los componentes del servicio, que pueden variar en granularidad de un solo módulo a una gran parte de la aplicación. Los componentes de servicio contienen uno o más módulos (por ejemplo, clases de Java) que representan una función de un solo propósito (por ejemplo, proporcionar el tiempo para una ciudad o ciudad específica) o una parte independiente de una aplicación empresarial grande. Diseñar el nivel adecuado de granularidad del componente de servicio es uno de los mayores desafíos dentro de una arquitectura de microservicios.

Otro concepto clave dentro del patrón de arquitectura de microservicios es que es una arquitectura distribuida, lo que significa que todos los componentes dentro de la arquitectura están completamente desacoplados entre sí y se accede a través de algún tipo de protocolo de acceso remoto (por ejemplo, JMS, AMQP, REST, SOAP, RMI, etc.). La naturaleza distribuida de este patrón de arquitectura es cómo consigue algunas de sus características de escalabilidad y despliegue superiores.


Existen docenas de implementaciones de este patrón arquitectonico, pero las más comunes son: basado en un API REST, basado en una aplicación REST y de mensajería centralizada.

La topología de API REST es útil para los sitios web que desean exponer servicios atravez de una API. Un ejemplo de estos son las APIs que proveen servicios de Google, Yahoo o/y Amazon.


La topologia basada en REST es un tanto diferente a la anterior dado que las solicitudes del cliente se reciben a través de pantallas de aplicaciones empresariales tradicionales basadas en web o en clientes en lugar de a través de una simple capa API. La capa de interfaz de usuario de la aplicación se despliega como una aplicación web separada que accede de forma remota a componentes de servicio desplegados por separado (funcionalidad empresarial) a través de simples interfaces basadas en REST. Los componentes de servicio en esta topología difieren de los de la topología basada en API-REST en que estos componentes de servicio tienden a ser más grandes, de grano más grueso y representan una pequeña porción de la aplicación empresarial general. Esta topología es común para las aplicaciones empresariales pequeñas y medianas que tienen un grado relativamente bajo de complejidad.


Otro enfoque común dentro del patrón de arquitectura de microservicios es la topología de mensajería centralizada. Esta topología es similar a la topología anterior basada en REST, excepto que en lugar de usar REST para acceso remoto, esta topología utiliza un intermediario de mensajes centralizado ligero (por ejemplo, ActiveMQ, HornetQ, etc.). Es de vital importancia al considerar esta topología no confundirlo con el patrón de arquitectura orientada al servicio o considerarlo "SOA-Lite". El agente de mensajes ligeros que se encuentra en esta topología no realiza ninguna orquestación, transformación o enrutamiento complejo. Es sólo un transporte ligero para acceder a los componentes de servicio remotos.

La topología de mensajería centralizada se encuentra típicamente en aplicaciones de negocios más grandes o aplicaciones que requieren un control más sofisticado sobre la capa de transporte entre la interfaz de usuario y los componentes de servicio. Los beneficios de esta topología sobre la simple topología basada en REST discutida anteriormente son mecanismos avanzados de colas, mensajería asíncrona, monitoreo, manejo de errores y mejor balanceo de carga y escalabilidad. El único punto de fallo y los problemas de cuello de botella arquitectónico generalmente asociados con un intermediario centralizado se abordan a través de la agrupación de intermediarios y de la federación de intermediarios (dividir una única instancia de intermediario en múltiples instancias de intermediario para dividir la carga de procesamiento de mensajes en función de las áreas funcionales del sistema).

El patrón de arquitectura de microservicios resuelve muchos de los problemas comunes encontrados tanto en aplicaciones monolíticas como en arquitecturas orientadas a servicios. Dado que los principales componentes de la aplicación se dividen en unidades más pequeñas, desplegadas por separado, las aplicaciones creadas utilizando el patrón de arquitectura de microservicios son generalmente más robustas, proporcionan una mejor escalabilidad y pueden soportar más fácilmente la entrega continua.

Otra ventaja de este patrón es que proporciona la capacidad de realizar despliegues de producción en tiempo real, lo que reduce significativamente la necesidad de los tradicionales despliegues mensuales o de fin de semana de "big bang". Dado que el cambio se suele aislar a componentes de servicio específicos, sólo es necesario desplegar los componentes de servicio que cambian. Si sólo tiene una única instancia de un componente de servicio, puede escribir código especializado en la aplicación de interfaz de usuario para detectar un despliegue en caliente activo y redirigir a los usuarios a una página de error o una página de espera. Alternativamente, puede intercambiar varias instancias de un componente de servicio durante y después de una implementación en tiempo real, lo que permite una disponibilidad continua durante los ciclos de implementación (algo que es muy difícil de hacer con el patrón de arquitectura en capas).

Una última consideración a tener en cuenta es que, dado que el patrón de arquitectura de los micro-servicios es una arquitectura distribuida, comparte algunos de los mismos problemas complejos encontrados en el patrón de arquitectura impulsado por eventos, incluyendo creación de contrato, mantenimiento y administración, disponibilidad remota del sistema, autenticación y autorización de acceso remoto.