Las arquitecturas software orientadas a microservicios se están convirtiendo en un standard para la construcción de aplicaciones modernas desplegadas continuamente en plataformas Cloud.

Martin Fowler, uno de los firmantes del Manifiesto Ágil y una de las personas más influyentes en el mundo del software, profundizó en el concepto de arquitecturas orientadas a microservicios en este artículo de obligada lectura.

Sin duda este nuevo estilo de arquitectura se está imponiendo en entornos donde las necesidades de escalabilidad son muy fuertes y el diseño en componentes independientes es una gran ventaja a la hora de abordar problemas complejos.

En Paradigma hemos escrito varios artículos profundizando en diferentes aspectos a tener en cuenta a la hora de enfrentarse a arquitecturas orientadas a microservicios como la orquestación, la monitorización o el despliegue.

En este artículo, sin embargo, queremos profundizar en una de las grandes ventajas de los microservicios: el poliglotismo.

¿Por qué desarrollar microservicios en Python?

Uno de los principios de este estilo de arquitectura es que los servicios deben de tender a ser lo más cohesionados posibles, minimizando al máximo el acoplamiento entre ellos.

La comunicación entre los servicios se ha de implementar a través de mecanismos ligeros, preferiblemente APIs basados en HTTP, como por ejemplo APIs RESTful/JSON.

Estos sistemas de comunicación agnósticos nos abren la puerta a que podamos desarrollar cada microservicio con el lenguaje y las herramientas que más nos convenga en cada caso.

Por ejemplo, si en un microservicio en concreto el rendimiento es un aspecto crítico, podemos escoger lenguajes de bajo nivel que nos permitan afinar más este aspecto como C, C++ o Go.

Sin embargo en otros casos nos interesará escoger lenguajes de alto o nivel o que implementen ciertas características particulares, como Python, Ruby, Groovy o Scala, que nos permitan avanzar más rápido o se acomoden mejor al servicio que deben implementar.

Llegados a este punto debemos plantearnos qué opciones o plataformas pueden ser interesantes a la hora de implementar estos servicios que exponen APIs REST más allá de los lenguajes que nos ofrece la JVM y de los frameworks habituales en el ecosistema Java, en ocasiones demasiado pesados.

Sin duda una de las mejores opciones a tener en cuenta es usar un lenguaje de alto nivel como Python, del que podemos aprovechar muchas de sus ventajas ya que es un lenguaje interpretado y de tipado dinámico.

Python es ampliamente utilizado, por lo que tiene una gran base de programadores. Combina múltiples paradigmas de programación como el orientado a objetos y el funcional.

Además, su sintaxis está orientada escribir menos líneas de código pero más claras que otros lenguajes, lo que facilita enormemente su mantenimiento.

Por otro lado, existen excelentes frameworks y bibliotecas muy asentados y orientados al desarrollo de APIs REST y sistemas de comunicación basados en HTTP, lo que es perfecto para la construcción de microservicios.

Algunos de los frameworks más interesantes para construir APIs REST son:

Ejemplo

Vamos a ver un ejemplo de cómo construir en pocas líneas un pequeño microservicio que exponga un API REST para manejar “customers” con Django y REST Framework.

En este caso vamos a tener que definir los siguientes elementos, cada uno en un fichero Python:

models.py

En este fichero vamos a definir cómo será nuestro modelo “Customer”, esto lo hacemos a través de la definición de una clase que herede de “Model”. Esta clase incluirá una serie de propiedades y sus tipos de datos que serán los atributos que tendrá un cliente.

El ORM de Django convertirá esta información en una tabla en la base de datos que elijamos.


from django.db.models import Model, UUIDField, CharField, EmailField, DateTimeField
class Customer(Model):
    id = UUIDField(primary_key=True)
    name = CharField(max_length=45)
    surname = CharField(max_length=45)
    phone = CharField(max_length=45)
    email = EmailField()

views.py


from rest_framework import viewsets
from customer.models import Customer
from customer.serializers import CustomerSerializer
class CustomerViewSet(viewsets.ModelViewSet):
    model = Customer
    queryset = Customer.objects.all()
    serializer_class = CustomerSerializer

En la vista le indicamos a Django que queremos basarnos en el modelo “Customer”, que hemos definido para construir un API asociada a este modelo.

Al heredar de “ModelViewSet” el API que expondremos será CRUD y ofrecerá los siguientes métodos:

Además le indicamos que para la representación del recurso “Customer” debe de usar la clase “CustomerSerializer”.

urls.py


from rest_framework.routers import DefaultRouter
from customer.views import CustomerViewSet
router = DefaultRouter()
router.register('customers', CustomerViewSet, 'Customer')
urlpatterns = router.urls

En el fichero de URLs se define el punto desde el cual colgará el API de customer, en este caso será en /customers/ y desde aquí colgarán el resto de URLs asociadas a este recurso.

serializers.py


from rest_framework import serializers
from customer.models import Customer
class CustomerSerializer(serializers.ModelSerializer):
    class Meta:
        model = Customer

Los serializadores nos permiten implementar cambios en la representación y serialización de los recursos, limitar la información que devolverá el API y con qué estructura.

En este caso dejamos que el framework infiera del modelo los campos y los renderice todos de acuerdo a su tipo de datos. Esta sería la opción predeterminada.

tests.py


from django.core.urlresolvers import reverse
from rest_framework import status
from rest_framework.test import APITestCase
from customer.models import Customer
class AccountTests(APITestCase):
    def test_create_customer(self):
        url = reverse('customer-list')
        data = {
            'id': '550e8400-e29b-41d4-a716-446655440000',
            'name': 'John',
            'surname': 'Smith',
            'email': 'jsmith@test.com',
            'phone': '609148275'
        }
        response = self.client.post(url, data, format='json')
        self.assertEqual(response.status_code, status.HTTP_201_CREATED)
        self.assertEqual(Customer.objects.count(), 1)
        self.assertEqual(Customer.objects.get().name, 'John')

Por último definiremos un juego de tests que pruebe nuestra API. En este caso, a modo de ejemplo, definiremos un único test que envíe una petición POST con un body de ejemplo y haga las siguientes comprobaciones:

Documentación del API

Podemos navegar por el API que acabamos de generar usando la herramienta que nos viene incluida con Django Rest Framework.

Navegamos por el API usando la herramienta que nos viene incluida con Django Rest Framework.

También podemos activar fácilmente otros sistemas de documentación de APIs como Swagger que se integran perfectamente con Django a través del paquete django-rest-swagger.

podemos activar fácilmente otros sistemas de documentación de APIs como Swagger que se integran perfectamente con Django a través del paquete django-rest-swagger.

Conclusión

El estilo de arquitectura orientado a microservicios nos permite integrar diferentes lenguajes y frameworks, de esta forma podemos aprovechar lo mejor de cada uno. Python es un lenguaje moderno y muy potente para el desarrollo rápido de microservicios.

Además, combinado con los frameworks y herramientas del ecosistema Python, lo convierten, sin duda, en una alternativa muy interesante.

¿Te has quedado con ganas de más?

No te pierdas nuestro post ¿Cómo construir microservicios en Python? para profundizar más aún en el ecosistema de los microservicios.

Cuéntanos qué te parece.

Los comentarios serán moderados. Serán visibles si aportan un argumento constructivo. Si no estás de acuerdo con algún punto, por favor, muestra tus opiniones de manera educada.

Suscríbete

Estamos comprometidos.

Tecnología, personas e impacto positivo.