sábado, 15 de agosto de 2026

¿Por qué Erlang sigue vivo en 2026 ... ?

En una anterior entrega ya habíamos hablado sobre el tema.

Mencionamos que el lenguaje Erlang había nacido para problemas que aún son vigentes:

  • Millones de conexiones simultáneas. 
  • Sistemas distribuidos globales. 
  • Microservicios que no pueden caerse. 
  • Plataformas con latencia estable y operación 24/7 sin downtime.

Quienes vienen de lenguajes como Java o C# deberán cambiar la forma de pensar si es que quieren aprender este lenguaje. La razón es simple: el paradigma de programación de sistemas que usa Erlang es completamente diferente.

Cambios fundamentales en el paradigma

No solo es sintaxis, es un cambio de la forma en la que piensas. El programador incipiente deberá entender que Erlang es diferente, veamos algunos cambios importantes:

  • Orientación a objetos vs. Modelo de Actores: En Java/C# piensas en clases, interfaces y objetos que comparten memoria y métodos. En Erlang no hay clases ni objetos; todo son procesos ligeros que no comparten memoria y se comunican únicamente mediante el envío explícito de mensajes asíncronos. 
  • Estado mutable vs. Inmutabilidad: Olvídate de modificar variables o campos de una clase. En Erlang todas las variables son inmutables. El estado se gestiona mediante recursión y pasando el nuevo estado como argumento a la siguiente llamada de función. 
  • Manejo de errores (Let it crash): En lugar de llenar tu código con bloques try/catch defensivos para cada excepción posible, la filosofía de Erlang es dejar que el proceso falle. Un supervisor detectará la caída y reiniciará el proceso automáticamente a un estado limpio conocido. 
  • Tipado dinámico vs. Estático: Erlang utiliza tipado dinámico en tiempo de ejecución. Para compensar la falta de verificación en compilación que tienes en C# o Java, la comunidad depende fuertemente de Dialyzer (análisis estático) y especificaciones de tipos (-spec).

Breve comparativa entre BEAM y JVM

La máquina virtual de Erlang (BEAM) y la máquina virtual de Java (JVM) en comparativa:

En pocas palabras, estas herramientas hacen prácticamente lo mismo. Cada una con sus propias peculiaridades.

Conceptos clave del ecosistema OTP

Los conceptos que deberás entender:

  • OTP (Open Telecom Platform): Erlang casi nunca se usa "a secas"; se utiliza junto con OTP, que es la librería estándar de patrones de diseño distribuidos. 
  • GenServer: El equivalente a una clase de servicio o Singleton que mantiene un estado y responde a llamadas sincrónicas o asíncronas. 
  • Supervisores: Procesos cuyo único trabajo es monitorear a otros procesos y aplicar estrategias de reinicio cuando alguno falla. 
  • Hot Code Swapping: La capacidad nativa del runtime para actualizar el código de una aplicación en producción sin detener el sistema ni perder conexiones activas.

Buenas prácticas y herramientas para 2026

Esto es lo que un programador debería tomar en cuenta a la hora de empezar con este lenguaje:

  • Pattern Matching: Dominar la coincidencia de patrones es esencial; se utiliza en la asignación de variables, en los argumentos de las funciones y en la extracción de mensajes. 
  • Herramientas de construcción: La herramienta estándar moderna para gestionar proyectos, dependencias y compilación en Erlang es rebar3
  • Ecosistema BEAM y Elixir: La máquina virtual de Erlang se llama BEAM. Elixir corre sobre la misma VM y comparte la misma interoperabilidad. Conocer Erlang te da acceso directo a todo el ecosistema de BEAM.

¿Para qué aprender Erlang?

Aprender Erlang te otorga un entendimiento profundo del motor runtime (BEAM). Lo que permite dominar Elixir y crear arquitecturas capaces de manejar millones de eventos en tiempo real.

Erlang se aplica en problemas donde la caída de un servidor representa pérdidas millonarias o fallos críticos:

  • Telecomunicaciones y Mensajería: Gestión de switches de señalización (VoIP), procesamiento de mensajería masiva en tiempo real y componentes de red donde el tiempo de actividad (uptime) debe ser del 99.999%. 
  • Plataformas Fintech y Pagos: En el ecosistema fintech mexicano (con cientos de empresas activas procesando transacciones), Erlang/Elixir se usa para motores de procesamiento de pagos, autorizaciones SPEI de alta frecuencia y sistemas transaccionales con tolerancia a fallos. 
  • Internet de las Cosas (IoT) y Redes: Manejo de gateways que reciben telemetría constante de miles de sensores o dispositivos conectados simultáneamente sin colapsar el hilo principal. 
  •  Infraestructura Backend y Cuchillería de Sistemas: Procesamiento de colas de mensajes distribuidas (como las basadas en RabbitMQ) y motores de base de datos distribuidos (como CouchDB o Riak).

En el mundo laboral actual, Erlang (y su hijo Elixir) es uno de esos lenguajes "raros" que muy pocas personas dominan o emplean de manera profesional. La mayoría de las empresas prefieren lenguajes conocidos como Java, C# y Python para sus desarrollos. Incluso lenguajes como COBOL siguen vigentes y con una importante demanda.

En países de Europa y USA existen vacantes. En países como México es poca la demanda, la mayoría ofertas de trabajo remoto.

¿Por qué Erlang sigue vivo en 2026? Porque resuelve problemas que aún existen... y existirán en un futuro.

Enlaces:

https://codemonkeyjunior.blogspot.com/2021/06/erlang-sitios-para-aprender.html



sábado, 25 de julio de 2026

Pattern Matching en sencillas palabras (o no tanto)

El pattern matching es una técnica para comparar estructuras de datos contra un patrón y, si coincide, extraer valores o ejecutar lógica específica. Es más expresivo que simples condicionales (if/else o switch) porque permite desestructurar objetos, listas, tuplas, enums, etc., directamente en la condición.

Digamos que es como un switch evolucionado que no solo compara valores, sino que entiende la forma y contenido de los datos.

¿Para qué sirve?

  • Simplificar código: menos if anidados y menos boilerplate. 
  • Mayor expresividad: describe qué esperas de los datos, no cómo acceder a ellos. 
  • Seguridad en tiempo de compilación: muchos lenguajes obligan a cubrir todos los casos (ej. sealed classes en Kotlin, enum en Rust). 
  • Desestructuración directa: extraer valores sin escribir getters o índices.

En teoría el pattern matching nos obligará a escribir un código más limpio y fácil de leer, evitar errores y extraer datos directamente.

Usando otras palabras, el pattern matching (coincidencia de patrones) es como una súper versión del famoso if / else o del switch que usan muchos lenguajes de programación, pero con "esteroides".

En lugar de solo preguntar ¿Esta variable es igual a 5?, el Pattern Matching te permite preguntar:

"¿Esta información tiene la estructura o la forma que estoy buscando? Y si es así, extrae los datos que me interesan de una vez."


Pattern Matching

Observemos un ejemplo:

// Using Pattern Matching:

switch(response) {
case Success(data):
display("Todo salió bien, los datos son: " + data)

case Error(code, message):
display("Error con el código " + code+ ": " + message)

case Loading:
display("Espere por favor...")
}

Originalmente nació dentro del paradigma de programación funcional.

Actualmente está técnica se puede usar en lenguaje de programación modernos como Go, Rust, Scala, Java, Kotlin, y C#.

En Java:

switch (obj) {
case String s -> System.out.println("Texto: " + s);
case Integer i -> System.out.println("Número: " + i);
default -> System.out.println("Otro tipo");
}

En C#:

object o = 42;
if (o is int x) Console.WriteLine(x);
switch (o) {
case string s: Console.WriteLine($"Texto {s}"); break;
case int i when i > 0: Console.WriteLine($"Positivo {i}"); break;
}

En Kotlin:

sealed class Expr class Num(val value: Int): Expr()

class Sum(val left: Expr, val right: Expr): Expr()

fun eval(e: Expr): Int = when(e) { is Num -> e.value is Sum -> eval(e.left) + eval(e.right)}

En Go:

switch v := anyVal.(type) {
case string:
fmt.Println("Texto", v)
case int: fmt.Println("Número", v)
}

Un ejemplo sencillo de entender

Tomemos este pseudo código que verifica si la edad de una persona es igual 18. Si lo es, puede votar. Si no es el caso, no puede votar.

var edad: int = 45

if edad -equals 18 then
  display 'Puedes votar'.
else 
  display 'No puedes votar'.
end if

Aplicando la lógica del patter matching tenemos este código en Haskell, un lenguaje puramente funcional.

votar.hs

edad :: Int
edad = 45

mensaje :: String
mensaje = case edad of
    18 -> "Puedes votar"
    _  -> "No puedes votar"

main :: IO ()
main = putStrLn mensaje

Si lo ejecutamos:

$ runghc votar.hs

La salida será:

No puedes votar

¿Acaso es un error de código? No y sí. No porque el código está haciendo lo correcto, si la edad no es 18 el usuario no podrá votar. Sí es error en cuanto a que el valor es 45 y es obvio que es mayor a 18. Debería poder votar. Modifiquemos el programa.

votar.hs

puedeVotar :: Int -> String
puedeVotar edad
    | edad >= 18 = "Puedes votar"
    | otherwise  = "No puedes votar"

main :: IO ()
main = putStrLn (puedeVotar 45)

Si lo volvemos a ejecutar:

$ runghc votar.hs

La salida será:

 Puedes votar

Podríamos continuar con más ejemplo, pero creo que es mejor detenernos.

El pattern matching se ha popularizado así como la programación funcional. Lenguajes como Java y C# lo implementan en sus versiones más actuales.

Es una forma que nos obliga a escribir mejor código y olvidarnos de los if anidados y complejos switch.

Enlaces:

https://en.wikipedia.org/wiki/Pattern_matching
https://emanuelpeg.blogspot.com/search?q=pattern+matching



domingo, 19 de julio de 2026

JDBI con Spring Boot

JDBI es una librería de código abierto para Java que actúa como una capa de abstracción sobre JDBC (Java Database Connectivity).

Permite interactuar con bases de datos relacionales de forma más rápida y limpia, reduciendo el código repetitivo (boilerplate) sin ocultar el lenguaje SQL.

Creando un proyecto Spring Boot con JDBI

Iremos al sitio para crear nuestro proyecto: https://start.spring.io/

Agregaremos las dependencias de MariaDB y Spring Jdbc.

Una vez creado el proyecto agregaremos una más, la dependencia de JDBI:

pom.xml

        <dependency>
            <groupId>org.jdbi</groupId>
            <artifactId>jdbi3-core</artifactId>
            <version>3.2.5</version>
        </dependency>
        <dependency>
            <groupId>org.jdbi</groupId>
            <artifactId>jdbi3-sqlobject</artifactId>
            <version>3.2.5</version>
        </dependency>
        <dependency>
            <groupId>org.jdbi</groupId>
            <artifactId>jdbi3-spring5</artifactId> 
            <version>3.2.5</version>
        </dependency>

El diseño de nuestra aplicación será modular:

  • repository: para el acceso a los datos de la BD. 
  • model: para el mapeo objeto-relacional. 
  • service: contiene la lógica de negocio. 
  • controller: el punto de entrada de las peticiones HTTP.
  • config: para las configuraciones.

Base de datos de la aplicación

Usaremos MariaDB como BD. El nombre de la BD sera ``soporte_tecnico``. Nuestra tabla es la siguiente:

CREATE OR REPLACE TABLE usuarios(
id int PRIMARY KEY, password varchar(255),
nombre varchar(255), apellidos varchar(255),
correo varchar(255), cvesis varchar(255)
);

Esta entidad relacional describe los atributos de un usuario.

Capa de mapeo objeto-relacional

Crearemos nuestra clase tipo que mapee los atributos de la tabla usuarios.

Usuario.java

package com.codemonkey.demo_jdbi.model;

import org.jdbi.v3.core.mapper.reflect.ColumnName;
import org.jdbi.v3.core.mapper.reflect.JdbiConstructor;

public class Usuario {
    @ColumnName("id") private Long id;
    @ColumnName("nombre") private String nombre;
    @ColumnName("apellidos")private String apellidos;
    @ColumnName("correo") private String correo;
    @ColumnName("cvesis")private String cvesis;


   public Usuario(
    @ColumnName("id") Long id,
    @ColumnName("nombre") String nombre,
    @ColumnName("apellidos") String apellidos,
    @ColumnName("correo") String correo,
    @ColumnName("cvesis") String cvesis) {
    this.id = id;
    this.nombre = nombre;
    this.apellidos = apellidos;
    this.correo = correo;
    this.cvesis = cvesis;
	}


    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getNombre() {
        return nombre;
    }

    public void setNombre(String nombre) {
        this.nombre = nombre;
    }

    public String getApellidos() {
        return apellidos;
    }

    public void setApellidos(String apellidos) {
        this.apellidos = apellidos;
    }

    public String getCorreo() {
        return correo;
    }

    public void setCorreo(String correo) {
        this.correo = correo;
    }

    public String getCvesis() {
        return cvesis;
    }

    public void setCvesis(String cvesis) {
        this.cvesis = cvesis;
    }
}

No incluiremos el campo del password.

Capa de datos

Crearemos una interface para el repositorio de datos.

UsuarioRepository.java

package com.codemonkey.demo_jdbi.repository;

import com.codemonkey.demo_jdbi.model.Usuario;
import org.jdbi.v3.sqlobject.config.RegisterConstructorMapper;
import org.jdbi.v3.sqlobject.statement.SqlQuery;
import org.jdbi.v3.sqlobject.statement.SqlUpdate;
import java.util.List;

@RegisterConstructorMapper(Usuario.class) 
public interface UsuarioRepository {

    @SqlQuery("SELECT id, nombre, apellidos, correo, cvesis FROM usuarios")
    List<Usuario> listarUsuarios();

    @SqlUpdate("INSERT INTO usuarios(id, password, nombre, apellidos, correo, cvesis) VALUES (:id, :password, :nombre, :apellidos, :correo, :cvesis)")
    void insertar(Long id, String password,String nombre, String apellidos, String correo, String cvesis);
}

Esta interface tendrá dos métodos. Uno para consultar los datos con la instrucción SELECT y otro para insertar datos con INSERT.

Capa del servicio

Crearemos una clase tipo service para la lógica del negocio.

UsuarioService.java

package com.codemonkey.demo_jdbi.service;

import com.codemonkey.demo_jdbi.model.Usuario;
import com.codemonkey.demo_jdbi.repository.UsuarioRepository;
import org.jdbi.v3.core.Jdbi;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class UsuarioService {

    private final UsuarioRepository usuarioRepository;

    public UsuarioService(Jdbi jdbi) {
        this.usuarioRepository = jdbi.onDemand(UsuarioRepository.class);
    }

    public List<Usuario> listarUsuarios() {
        return usuarioRepository.listarUsuarios();
    }

    public void insertarUsuario(Long id, String password, String nombre, String apellidos, String correo, String cvesis) {
        usuarioRepository.insertar(id, password, nombre, apellidos, correo, cvesis);
    }
}

Capa para el acceso a las peticiones HTTP

Crearemos una clase tipo controller.

UsuarioController.java

package com.codemonkey.demo_jdbi.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResquestBody;
import java.util.logging.Logger; import java.util.logging.Level; import com.codemonkey.demo_jdbi.service.UsuarioService; import com.codemonkey.demo_jdbi.model.Usuario; import java.util.List; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @RestController @RequestMapping("/api/usuarios") public class UsuarioController { private static final Logger LOGGER = Logger.getLogger(UsuarioController.class.getName()); private UsuarioService usuarioService; @Autowired public UsuarioController(UsuarioService usuarioService) { this.usuarioService = usuarioService; } // http://localhost:8083/api/usuarios/hola @GetMapping("/hola") public String hola() { LOGGER.log(Level.INFO, "Entramos al primer servicio."); return "El servicio esta vivo."; } // http://localhost:8083/api/usuarios/all @GetMapping("/all") public ResponseEntity<List<Usuario>> getUsuarios() { LOGGER.info("\t ==== Obtenemos todos los usuarios. ===="); List<Usuario> usuarios = usuarioService.listarUsuarios(); if(usuarios.isEmpty()) { return ResponseEntity.noContent().build(); } return ResponseEntity.ok(usuarios); } // http://localhost:8083/api/usuarios/insertar @PostMapping("/insertar") public ResponseEntity<String> insertarUsuario(@RequestBody Usuario usuario) { try { LOGGER.info("Insertando nuevo usuario: " + usuario.getNombre()); usuarioService.insertarUsuario( usuario.getId(), "qwErt@3200$", usuario.getNombre(), usuario.getApellidos(), usuario.getCorreo(), usuario.getCvesis() ); return ResponseEntity.status(HttpStatus.CREATED) .body("Usuario insertado correctamente."); } catch (Exception e) { LOGGER.log(Level.SEVERE, "Error al insertar usuario", e); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) .body("Error al insertar usuario: " + e.getMessage()); } } }

Esta clase expone tres apis:

  • GET http://localhost:8083/api/usuarios/hola 
  • GET http://localhost:8083/api/usuarios/all 
  • POST http://localhost:8083/api/usuarios/insertar

La primera es para probar que la aplicación está activa. La segunda para consultar todos los datos de la tabla usuarios. La tercera para agregar un nuevo usuario.

Construimos la aplicación:

$ mvn clean install -X

Ejecutamos la aplicación:

$ mvn spring-boot:run

Hemos visto cómo crear una aplicación Spring Boot con Jdbi.

Enlaces:

https://jdbi.org/
https://codemonkeyjunior.blogspot.com/2016/02/jdbi-como-alternativa-jdbc.html
https://codemonkeyjunior.blogspot.com/2016/01/conociendo-jdbi.html
https://codemonkeyjunior.blogspot.com/2017/04/jdbi-con-groovy-2.html


viernes, 10 de julio de 2026

¿Cómo funcionan los flujos en MuleSoft?

En la anterior entrega vimos que MuleSoft es una herramienta que nos permite conectar aplicaciones, datos y APIs de manera centralizada.

Ahora veremos cómo funciona los flujos de MuleSoft.

Flujo de una aplicación Spring Boot con Mulesoft

Digamos que se tiene una API con Spring Boot y se quiere integrar mediante MuleSoft.

┌─────────────────┐
 Aplicación      
 Consumidora     
 (Web/Móvil/ERP) 
└────────┬────────┘
          HTTPS/REST
         
┌─────────────────┐
 MuleSoft API    
 Experience API  
└────────┬────────┘
         
          Validación
          Seguridad (OAuth/JWT)
          Rate Limit
         
┌─────────────────┐
 Mule Flow       
 Orquestación    
└────────┬────────┘
         
         ├─────────────┐
                      
                      
┌────────────┐   ┌─────────────┐
 Transform      Enriquecer  
 DataWeave      Datos       
└─────┬──────┘   └──────┬──────┘
                       
      └────────┬────────┘
               
     ┌─────────────────┐
      System API      
      Spring Boot API 
     └───────┬─────────┘
              REST/JSON
             
     ┌─────────────────┐
      Spring Boot     
      Business Logic  
     └───────┬─────────┘
             
             
     ┌─────────────────┐
      Base de Datos   
      MySQL/Postgres  
     └─────────────────┘
	 
	 

Esto nos muestra el flujo de la aplicación con Mulesoft.

Flujo detallado (Spring Boot)

Todo inicia desde la petición del cliente hasta obtener la respuesta.

Cliente
   
   
HTTP Listener
   
   
Validar JWT/OAuth
   
   
Logger Request
   
   
Transform Message
(DataWeave)
   
   
HTTP Request
(Spring Boot API)
   
   
Spring Boot
   
   ├── Consulta DB
   ├── Procesa lógica
   └── Devuelve JSON
   
   
Transform Response
(DataWeave)
   
   
Logger Response
   
   
Retorna al Cliente

Teniendo una API Spring Boot:

GET /api/clientes/123

Respuesta:

{
  "id": 123,
  "nombre": "Thomas Muller",
  "email": "thomas.muller@empresa.com"
}

Exponiendo una API corporativa con MuleSoft:

GET /clientes/123

Respuesta:

{
  "id": 123,
  "nombre": "Thomas Muller",
  "email": "thomas.muller@empresa.com"
}

Arquitectura API-Led Connectivity

MuleSoft recomienda tres capas:

                 CLIENTES
                     
                     
        ┌─────────────────────────┐
         Experience API          
         Web / Mobile / Partner  
        └──────────┬──────────────┘
                   
                   
        ┌─────────────────────────┐
         Process API             
         Orquestación negocio    
        └──────────┬──────────────┘
                   
         ┌─────────┴─────────┐
                            
┌────────────────┐  ┌────────────────┐
 System API        System API     
 Spring Boot       SAP / Oracle   
└────────┬───────┘  └────────────────┘
         
         
   ┌──────────┐
    Database 
   └──────────┘

Responsabilidad de cada API

  • Experience API: adapta la información para cada canal.
  • Process API: aplica reglas de negocio y orquesta sistemas.
  • System API: conecta directamente con Spring Boot, SAP, Salesforce, bases de datos, etc.

Ejemplo de Mule Flow XML

Observemos un ejemplo de flujos (flow):

<flow name="getCustomerFlow">

    <http:listener
        path="/clientes/{id}"
        config-ref="HTTP_Listener"/>

    <logger
        level="INFO"
        message="Consultando cliente"/>

    <http:request
        method="GET"
        url="http://springboot:8080/api/clientes/#[attributes.uriParams.id]" />

    <ee:transform>
        <ee:message>
            <ee:set-payload>
<![CDATA[
%dw 2.0
output application/json
---
{
  customerId: payload.id,
  fullName: payload.nombre,
  contact: {
      email: payload.email
  }
}
]]>
            </ee:set-payload>
        </ee:message>
    </ee:transform>

</flow>

A simple vista es algo complejo estar trabajando con flujos, pero una vez aue se entiende la lógica ya no es tan complicado. Como se dijo arriba, todo inicia desde la petición del cliente hasta obtener una respuesta. Esa respuesta puede ser válida o indicar un error si la aplicación no puede atender correctamente la petición.

Beneficios de usar MuleSoft delante de Spring Boot:

  • Seguridad centralizada (OAuth, JWT, Client ID).
  • Monitoreo en Anypoint Platform.
  • Transformación de formatos con DataWeave.
  • Orquestación entre múltiples APIs.
  • Reutilización mediante API-Led Connectivity.
  • Desacoplamiento entre consumidores y backend Spring Boot.

Proyecto en AnyPoint Studio MuleSoft

AnyPoint Studio MuleSoft es un entorno de desarrollo integrado (IDE) basado en Eclipse. Permite a los desarrolladores diseñar, construir y probar APIs e integraciones empresariales mediante una interfaz visual de arrastrar y soltar, simplificando la conexión entre diferentes aplicaciones y servicios.

Un proyecto luciría de esta forma:

MuleSoft es un mundo por aprender; nos permite conectar sistemas, diseñar, crear, probar y gestionar APIs empresariales; además de facilita la automatización de procesos, denominados flujos de trabajo; también permite visualizar toda la infomación involucrada.

Continuaremos con este tema en próximas entregas.

Enlaces:

https://www.mulesoft.com/
https://es.wikipedia.org/wiki/MuleSoft
https://www.seidor.com/es-mx/blog/salesforce-mulesoft-que-es
https://rootstack.com/es/blog/mulesoft-todo-lo-que-tienes-que-saber


miércoles, 8 de julio de 2026

MuleSoft para desarrolladores de APIs

MuleSoft es una plataforma de integración que te permite conectar aplicaciones, datos y APIs de manera centralizada.

Para un desarrollador Java con Spring Boot, sirve como un puente que complementa su backend con capacidades de gestión de APIs, orquestación de servicios y conectividad con sistemas externos.

MuleSoft en pocas palabras

  1. Plataforma de integración: MuleSoft (con su runtime Mule 4) permite crear flujos de integración entre sistemas heterogéneos (bases de datos, servicios REST/SOAP, colas de mensajería, SaaS).
  2. Anypoint Platform: Incluye herramientas como Anypoint Studio (IDE), API Designer (para diseño contract-first), y API Manager (para aplicar políticas de seguridad, rate limiting, etc.).
  3. SDK para Java: Puedes extender Mule creando conectores y módulos en Java usando Maven y el Mule SDK.

¿Para qué sirve en tu contexto Spring Boot?

Como desarrollador Java con experiencia en Spring Boot, MuleSoft nos aporta:

Diseño contract-first: Puedes definir tu API en RAML u OAS en Anypoint Designer y luego implementar la lógica en Spring Boot. Esto asegura consistencia entre diseño y código.

Gestión de APIs: MuleSoft API Manager permite aplicar políticas como:

  • Validación JWT con Keycloak.
  • Rate limiting para proteger tu backend.
  • Control de tráfico y seguridad centralizada.

Integración embebida: Existe un Spring Boot Starter para Mule 4, que te permite correr Mule Runtime dentro de tu aplicación Spring Boot. Esto facilita:

  • Monitoreo con Spring Boot Admin.
  • Exposición de servicios de despliegue Mule vía REST.
  • Control de tráfico y seguridad centralizada.

Comparativa: Spring Boot vs MuleSoft

Tabla comparativa entre Spring Boot y MuleSoft:

Aspecto Spring Boot MuleSoft
Foco principal Desarrollo rápido de microservicios y APIs Integración, gestión y orquestación de APIs
Diseño API Implementación directa con Spring MVC Contract-first con RAML/OAS + mockeo
Gestión de tráfico Necesitas librerías externas (Resilience4j, Spring Cloud Gateway) Políticas listas en API Manager
Extensibilidad Beans, filtros, interceptores Conectores y módulos vía Mule SDK
Despliegue Microservicios en contenedores Integraciones como aplicaciones Mule, embebibles en Spring Boot

Consideraciones y trade-offs

  • Licenciamiento: MuleSoft Enterprise puede ser costoso; evalúa si tu proyecto requiere gestión avanzada de APIs o si basta con Spring Cloud Gateway.
  • Curva de aprendizaje: Aunque conoces Java, MuleSoft introduce conceptos propios (flows, connectors, RAML).
  • Complementariedad: No reemplaza Spring Boot, sino que lo potencia en escenarios de integración compleja.

MuleSoft puede ser algo complejo para aprender. Existen mucha información, tutoriales y cursos en internet que podrían servirte para aprender a usarlo.

Enlaces:

https://www.mulesoft.com/
https://es.wikipedia.org/wiki/MuleSoft
https://www.seidor.com/es-mx/blog/salesforce-mulesoft-que-es
https://rootstack.com/es/blog/mulesoft-todo-lo-que-tienes-que-saber

¿Por qué Erlang sigue vivo en 2026 ... ?

En una anterior entrega ya habíamos hablado sobre el tema. Mencionamos que el lenguaje Erlang había nacido para problemas que aún s...

Etiquetas

Archivo del blog