Anda di halaman 1dari 48

APUNTES MULESOFT

Ejemplos de proyectos en los que han usado MuleSoft: Roche, Airbus, Red Eléctrica, …

MuleSoft, formado por:

-API manager: manera en la que exponemos un servicio a un cliente (ejemplo:


ofrecer una web con métodos (get,put,…) que permite acceder a datos bancarios).

-RUNTIME manager: parte interna flujos,…

API: una interfaz que muestras a clientes en la cual se expone un servicio que va a consumir
ese cliente.

Tengo una entrada, y lo que necesito para almacenar mi salida es el data type (normalmente
es la salida de tipo jason). En la Api se definen funciones (quiero el número de aviones,…)

Una API podría ser una interfaz (manera en la que construyo una API): se define con un fichero
llamado RAML (lenguaje para crear una API dentro de MuleSoft), Web service (diferentes
operaciones que defino en un fichero que va a permitir comunicarme con el cliente), y un API
proxy (un proxy es una capa intermedia que securiza la info que está viajando desde el
frontEnd al backEnd: pongo una capa a mi código que protege mi API para que nadie pueda
acceder a esa información.

The interface implementig API es la parte visual, como se presente al cliente.

Web service: hay dos tipos: tipo rest y tipo SOAP. Métodos de comunicación que permite a dos
software, personas, bases de datos a intercambiar comunicación.

-SOAP web services: son más complejos de construir y entender, normalmente


lenguaje XML.

-RESTful: es más sencillo, va por URL. Hay 4 métodos principales: get, post (inserta
info), put (actualiza) delete (borrar). Da velocidad en la manera que da la solución al cliente.

Wsdl: extensión que se le pone al URL para . Arriba se definen las URL que vamos a usar.

Ejemplo de XML: Defino la estructura persona (por ejemplo persona es un string que tiene
para tantos elementos,…) eso es el data type.

<persona>

<nombre>Nely</nombre>

</edad>

</persona>

<nombre>Nely</nombre>: Es una estructura simple, no tiene hijas. Persona sería una


estructura compleja.
En el binding es donde se hacen las operaciones, es decir, los métodos, es decir, la información
que le interesa al cliente. Ejemplo: listame todos los vuelos, va a tener un request y un
Response.

RESTful web services: Representational State Transfer

Usan el HTTP protocol como frontEnd. Los métodos más usados son get, post delete.

URIs: parámetros que pasamos por URL.

Get: devuelven el actual estado del recurso (resource): devuelve la información que
solicitamos y el output puede devolverlo en tipo json o xml.

Post: se crea un nuevo recurso: hacemos un mensaje inicial y genera toda esa
información que le paso en el backend.

Delete: borra un recurso

Put: actualiza. El delete y Put se usan pasándole un ID que hace referencia al recurso
especifico.

Patch: cuando le damos al put podemos actualizar toda la información y el patch solo
actualiza parcialmente esa información. Por ejemplo: quiero actualizar el número de cuenta de
la persona pero no el nombre. Paso todo el recurso pero selecciono lo que quiero actualizar.

Ejemplo de RESTful

http://server:port/listAllFlights/4?destination=LAX

listAllFlights es la operación. Los uriparam son los que siguen con la barrita; los que siguen con
una interrogación se llaman query param. Se diferencian en la manera en la que filtran. Los
uriparam hace filtros sobre los recursos: quiero hacer un filtro sobre la lista flights (la
operación). Un query hace filtro sobre la información que a mí me devuelve, no sobre el
recurso. Por ejemplo, hasta 4 solo me va a dar el vuelo 4. Y lo que hay detrás de la
interrogación me va a devolver la información interna de ese recurso. Imaginamos que dentro
del recurso 4 tenemos algo con varios valores, como diferentes destinos. El vuelo 4 puede
tener diferentes destinos (LAX y GP). Esto último sería el queryparam.

Los URIparam son los parámetros que iniciamos inicialmente en la URL por los que filtramos.
Solo filtra recurso.

Los query param son parámetros que tienen un nombre (ID). Ej: quiero que me devuelvan los
listados de aviones donde el destination = LAX. Filtran la información de un recurso.

Un recurso es una clase y cada una tiene su ID. Si filtro por los atributos filtro por queryparam
y si filtro por clase, filtro por uriparam.

Mensaje tipo JSON:

Estructura: La lista se engloba en corchetes y las llaves para definir los recursos dentro de esa
lista. Entre un recurso y otro después de la llave ponemos una coma (menos el último recurso)

[
{

“ID”:”3”,

“Nombre1”:”MARÍA”,

“nombre2”:”PEREZ”

},

“ID”:”3”,

“nombre1”:”Isabel”,

“nombre2”:”nuñez”,

Dentro de REST hay una serie de herramientas para hacer llamadas de tipo REST. (Ejemplo
postman).

Dentro de Mule se puede ofrecer al cliente el API manager (diseño inicial) o el runtime. Hay
clientes que no necesitan el APImanager. Usaríamos el módulo del runtime. Si necesita de algo
visual necesitaríamos el modulo del APImanager. La API necesita ser securizada con secured
APIs. Estas requieren autentificación (accederíamos con una contraseña, token, client_id y
client_secret, política oauth,…) Podemos también con protocolos de autenticación, política de
seguridad con el oauth, SAML (tipo token), JWT (política propia que va por token),… hay un
montón.

CONCLUSIÓN: El diseño inicial de una API hay que securizarlo (YA VEREMOS COMO).

Toda llamada HTTP tiene un código de status (se devuelve si ha ido bien, mal, si la contraseña
del usuario es una mierda,…) El status code muestra al cliente como ha ido todo, y
normalmente va en el response (la estructura de respuesta llevará por tanto un status code:
http.status pondríamos).

Si no he picado en concreto por ejemplo el nombre que quiero que me filtre me daría uno de
estos códigos. Si se me cae el sistema me devuelve el 500.
POSTMAN: lo usamos para ver lo que nos devuelve el destino, para testear lo que he hecho

Es la herramienta de RESTful.

Partes:

URL: http://localhost:8081/listAllFlights

Auth: para securizar, poner seguridad.

Headers: cabeceras que se le añaden al mensaje. Tendremos un JSON (corchetes y llaves). La


cabecera es información adicional que le pongo a mi mensaje de entrada para poder
comunicarnos de manera correcta con el BackEnd. Le meto un token que me dice el cliente (ya
que él es el que me da autorización para usar sus datos).

Body: Puedo elegir la manera en la que envío mi información. Ejemplo: raw es en formato de
texto. Form-data lo uso cuando sé si mi proveedor me facilita la autenticación de clientes. Me
tendrían que decir el formato. Nosotros usaremos siempre el raw. Introduciremos la info de
nuestro recurso: Este body lo usaremos siempre para put y post (ya que en ellos añado
recursos, para actualizarlos y para que sean usados). Para get por ejemplo NO.

EJEMPLO: URL típica: http://training-amercian-ws.cloudhub.io/api/flights

Hay URL que vienen con la palabra api pero no tienen por qué tener api manager (solo la URL).

Meto esta URL en Postman en GET. Si le doy a enviar me sale los recursos que ha metido otro
tio picando. Si ahora elijo POST, le doy a body a raw en formato JSON (porque espero ese
lenguaje) y añadiría el recurso.

Para put y delete siempre tengo que filtrar por algo (añadir / y algo más en el URL) ya que para
actualizar o borrar algo tengo que pasar la info de qué. Para delete como lo que quiero es
borrar un recurso, borro por ID (añadiendo /7 por ejemplo) y no tengo que escribir en el body
lo que me borre en sí.
Cuando en las URL aparece la palabra /console/ es que hay una API de por medio. Si pongo esa
URL en la dirección de un explorer me sale la parte visual. De esa manera no hago que la otra
persona tenga que usar Postman y pueda acceder a una info que quiera recuperar:

Esa consola tiene types: donde vienen definidas las estructuras. En resources están los
métodos. Todo esto se hace por el lenguaje RAML. Con un fichero txt creo un fichero RAML.
Dentro del recurso /flights/{ID} tengo un queryparam para filtrar (ID). Al cliente le paso esta
consola y así no le paso el Postman que no va a entender.

Dentro del padre flights tengo Request donde tengo la descripción, queryparam si quiero,
esquema de seguridad para securizar la API,.. La response posible que tengo picada en RAML
es solo la respuesta 200 (en el ejemplo que estamos viendo).

http://training-american-api.cloudhub.io: Esta API (otro RAML) que está desplegado en otro


servidor al cual le han aplicado una política de seguridad porque los datos de esos vuelos no
quieren que nadie los vea. Si esto lo ponemos en Postman nos da error 401 porque no
tenemos autorización.

CONSTRUYENDO APIS:

Anypoint Design Center:

Management Center:

Anypoint Exchange:

Mule Runtime Engine (mis cajitas, flujos, variables, transformaciones,… todo lo que hago yo).

Anypoint Connectors: conectores con los que interactúo (diferentes cajas)

Runtime services: donde tengo desplegada mi aplicación (la aplicación que he construido con
mis cajas). Puedo hacer por un lado mi api, por otro mi runtime y fusionarlas para hacer por
ejemplo mi consola.

Hybrid cloud: diferentes servicios que te oferta Mule, o pagas por ellos o te los da de gratis
pero solo unos días.

A TODO ESTO LE AÑADO MI ANYPOINT STUDIO

Base URI es donde está contenida mi API. Aparece mi URL que puedo meter en internet.

DESIGN CENTER

Nuestros flujos, Mule los hace en design pero al ser una licencia gratuita no te deja hacer nada.
Asiq lo hacemos en el entorno de sannbox (esto es solo en el cloud de mule).

Cuando le doy a deploy se despliega en el sandbox en la nube. Cuando le doy a run se empieza
a generar en si y ver si la puedo correr en runtime.
RUNTIME:

En él se despliegan las aplicaciones que creamos y el estado bueno en que quedan es el started

Stop: paro la aplicación y debería darle a run otra vez.

Se crean .jar y .zip en la nube (en el anypoint solo .zip)

Nuestra primera caja (listener) tiene siempre un host (local host o 0.0.0.0) y un port.

Ejercicio de transformación = ejercicio de mapeo: mapeo lo que me viene de la entrada a la


salida. Podemos tener un input y generar una salida con los datos que nosotros queremos (lo
que me pide el cliente o lo que necesito para continuar mi flujo). Si mi cliente solo quiere lo
que vale el vuelo y la hora, cojo la entrada que tiene todos los campos y creo mi salida con solo
lo que quiere el cliente. Si después quiero transformar porque necesito además el porcentaje
de IVA, lo guardo este porcentaje en una variable. Voy construyendo la salida según el cliente
o lo que yo voy necesitando.

VAMOS A VER HOY TODO LO DE LAS CAJITAS, TRANSFORMACIÓN, TAMBIÉN CÓMO SE HACE
POR CÓDIGO (DATAWAY=NO POR CAJITAS), ACCEDER A UNA BASE DE DATOS (DATABASE) Y
CÓMO CREAR VARIABLES QUE GUARDEN NUESTRAS COSITAS

CAJAS que voy creando en el ejercicio:

Primero creo una caja con un http listener que pone en marcha mi
aplicación en un host/servidor/URL) y un puerto determinado (dentro de ese servidor tenemos
diferentes puertos, números, y son como agujeros de conexión donde la aplicación puede
estar activa runneando, normalmente se usa el 8081, 8283,… los puertos pueden estar
abiertos o cerrados. El path es lo que sigue a la URL, teniendo mi servidor …cómo puedo
acceder a continuación. Para iniciar la conversación hago un GET (lo establezco en la cajita) de
lo que va a venir, en este caso de lista de vuelo.

Creo otra caja Transform. El payload es la estructura de mis datos (no es el body).

Pongo un nombre (outputEjercicio1), formato (este caso json) y metemos en type un ejemplo
de una estructura, la estructura que queremos que aparezca en la salida. Deploy y run.
Copiamos el enlace en Postman.

(*En la nube cuando añado cajas mule intenta ejecutar lo que vamos haciendo y por eso te va
diciendo los errores pero en anypoint esto no pasa, no está mi desarrollo en tiempo de
ejecución, por eso a veces en mi transform no me genera*).

En el listener abro mi conexión y digo “en tal servidor y puerto está lo que hago”. Después
hago una llamada a un sistema externo (no es mi flujo, algo que yo estoy picando), salgo a la
nube y pido la info que quiero usar como la lista de vuelos. Después creo una transformación
para que la info salga de la manera que yo quiero.
EN ANYPOINT EN VEZ DE EN EL CLOUD:

Pulsamos botón derecho y creamos un proyecto. Se nos crea una carpeta con el burrito donde
está nuestra API en XML.

Carpetitas de la izqda.:

En la siguiente carpeta main api tenemos el RAML

El main resource lo usamos para meter las estructuras de nuestra transformación (por
ejemplo un .jsonexample

La mainwsdl

Las tres de despues son para guardar nuestros response, request,…

Cada entorno(cajita) tiene unas propiedades diferentes, un puerto diferente (8081, 8082,…)
por cada entorno y para no tener que estar cambiando continuamente el Port ponemos
${“nombre de la variable que me he creado en un fichero que he creado previamente para
definir todas las variables”}. Así solo diré que me ejecute el fichero init.properties

Vamos a picar nosotros mismo la variable: http.port=8081

URL: http / servidor (localhost) / puerto (8081) / base= basepath donde está mi aplicación
(ejer1)

Tenemos una URL por método.

Para definir mi URL estoy dentro de Message Flow (pestañita de debajo).

Para crear la cajita arrastro HTTP de la derecha y creo primero un listener que tiene que tener
un host y un port. Después arrastro otro HTTP pero al cuadrito de proceso.
En Anypoint la caja de transform no reconoce la salida de la otra caja como estructura de
entrada. Ahora no, tenemos que meterle a mano la estructura de entrada que viene del friki.
Esta está en un archivo que ella nos da.

Ejercicio 4

Ahora además de la caja listener le añadimos una caja Database. Vamos a acceder a una base
de datos y no a un URL. Para esto necesitamos un driver (solemos usar SQL)

Elijo como operación SELECT por ejemplo y escribimos lo que quiero obtener

El database me devuelve una serie de objetos y estos no están en un formato json. Mule
cuenta con un nodo adicional “object to json” y le digo que me traduzca a jason el objeto.

RAML:

https://raml.org/developers/raml-100-tutorial

Es la pate visual, la parte física. Internamente lo que recoge, analiza,.. es un flujo y eso ya se
hace con las cajas.

Un RAML es básicamente un fichero de texto donde tengo escrito un código. Dentro del RAML
hay cosas básicas que hay que poner siempre en el fichero y con lo que decimos que estamos
haciendo un RAML: Cabecera de toda RAML:

#%RAML 1.0

Title: myAPI

baseURI: http://localhost:8081/api (*aqui está desplegada mi api*)

version: v1

Existen dos versiones 1.0 y 0.8, ellos usan el 1.0 pero a medida que se aumentan las versiones
de mule las de RAML van bajando.

¿Qué es RAML?

RAML es el lenguaje específico de MuleSoft. La API es una arquitectura de lo que vamos a


tratar en la integración, es la parte visual y su lenguaje es el RAML.

Sirve para definir APIs con los servicios RESTful. Se definen recursos y dentro de ellos se hacen
llamadas a bases de datos (datatypes): puedo hacer GET de personas, pero la estructura de
persona (edad, altura,…) es el datatype y esto va importado como un fichero aparte en mi API.

Se pueden declarar también esquemas y esquemas de tipos JSON (este cambio lo hace
automáticamente).

RAML tiene internamente accesos a ficheros que pueden estar en .YAML o .JSON.
La identación es muy importante, si me salto un espacio peta todo el fichero, es decir que no
me corrige automáticamente y tengo que ir revisando línea por línea.

Los recursos son objetos que identifican al web service dentro de una URL. La URL era
http/local/flights. Flights era el recurso (va con una barra). Un URIparam se encierra por llaves.

DESIGN CENTER:

En design center creamos un mule specification. Le ponemos un titulo. Se crea donde vamos a
a escribir. Le tenemos que añadir lo primero una base: ejemplo:

baseUri: http://localhost:8081/api

Las herramientas están debajo

Para añadir recurso poner un /.

Estructura:
#%RAML 1.0
title: demo1
baseUri: http://localhost:8081/api

description: api de ejemplo

/Persona:
/Paciente:
/Medico:

Las responses son las posibles respuestas que me puede devolver el servidor. Quiero meterle
todas las posibles respuestas que me va a dar el bankEnd. Por ejemplo le pongo el 200 para
ese tipo de respuesta que quiero que me dé o el 400:

#%RAML 1.0
title: demo1
baseUri: http://localhost:8081/api
description: api de ejemplo

/Persona:
description: recurso Persona
/Paciente:
get:
#usamos un metodo get para listar todos los pacientes
responses:
200:
body:
application/json:
example: | detrás de los dos puntos pulso
tabulador y después control 1, le doy a intro para que se me baje
directamente y después otra vez al tabulador en la siguiente línea para
escribir: “…” ESTA BARRA SIEMPRE IRÁ CUANDO LO QUE VOY A METER ES A MANO.
SI LO VOY A IMPORTAR NO LO PONGO
"Todo ha ido bien"
401:
body:
application/json:
example: |
"No autorizado"

Un tío entra en esta consola y le aparece un GET. Si lo pulsa y todo va bien a él le aparece en
pantalla “todo ha ido bien” y no el listado de vuelos. Si lo dejo hasta application/json entonces
sí que le aparecería el listado de vuelos y estaría aceptando todo tipo de respuesta.

Todo lo que vaya después de example es lo que yo copio y pego y que me va a aparecer TAL
CUAL al pulsar en la consola GET. (*Anypoint era capaz en base de un example hacerte un tipo
de esquema*).

Si quiero usar un schema estoy diciéndole, pasándole un fichero donde tengo una estructura,
que lo que devuelva tiene que tener esa estructura. Estoy diciendo que lo que me manden
tiene que cumplir ese esquema de validación si no, no muestro esto. Yo hago un esquema que
valida lo que me va a mandar el cliente.

(*Con clientes NUNCA trabajaré con example porque yo estoy diciendo en ellos lo que quiero
que mande el servicio, y eso no tiene sentido*)

La estructura anterior la repito para todo:

#%RAML 1.0
title: demo1
baseUri: http://localhost:8081/api
description: api de ejemplo

/Persona:
description: recurso Persona
/Paciente:
get: #para extraer datos del paciente uso el método get
#usamos un metodo get para listar todos los pacientes
responses:
200:
body:
application/json:
example: |
"Todo ha ido bien"
401:
body:
application/json:
example: |
"No autorizado"
post: #para extraer datos del paciente uso el método get
#usamos un metodo get para listar todos los pacientes
responses:
200:
body:
application/json:
example: |
"Todo ha ido bien"

401:
body:
application/json:
example: |
"No autorizado"

put: #para extraer datos del paciente uso el método get


#usamos un metodo get para listar todos los pacientes
responses:
200:
body:
application/json:
example: |
"Todo ha ido bien"
401:
body:
application/json:
example: |
"No autorizado"

/Medico:

Persona es recurso padre, Paciente es recurso hijo.

El cliente quiere un get de todos los pacientes pero también que me filtre por DNI. Es decir,
quiero un URIparam (lo que va despues de la barra de pacientes y que sería un numero en la
URL). Para ello pongo:

/Persona:
description: recurso Persona
/Paciente:
/{DNI}:

responses:
200:
body:
application/json:
example: |
"Todo ha ido bien"
401:
body:
application/json:
example: |
"No autorizado"

Dependiendo de donde ponga mi get me hará el filtro sobre el recurso o sobre un Uniparam.

#%RAML 1.0
title: demo1
baseUri: http://localhost:8081/api
description: api de ejemplo

/Persona:
description: recurso Persona
/Paciente:
get: #para extraer datos del paciente uso el método get
#usamos un metodo get para listar todos los pacientes
responses:
200:
body:
application/json:
example: |
"Todo ha ido bien"
401:
body:
application/json:
example: |
"No autorizado"
/{DNI}:
get: #para extraer datos del paciente uso el método get
#usamos un metodo get para listar todos los pacientes
responses:
200:
body:
application/json:
example: |
"Todo ha ido bien"
401:
body:
application/json:
example: |
"No autorizado"

Puedo poner un get para el listado de los pacientes o sobre el recurso DNI.

Para poner queryparam:


/Persona:
description: recurso Persona
/Paciente:
get: #para extraer datos del paciente uso el método get
#usamos un metodo get para listar todos los pacientes
queryParameters:
nombre: #es un queryparameter y escribo sus props
displayName: Nombre #como quiero que aparezca en mi consola
type: string
description: nombre del susuario
required: true
example: Nely #con esto le hago ver el campo que tiene que
meter, le aparecerá el nombre pero él puede cambiarlo por el suyo, esto
es útil para por ejemplo la est de fechas
apellido:
displayName: Apellido
type: string
description: apellido del usuario
responses:
200:
body:
pplication/json:
example: |
"Todo ha ido bien"
401:
body:
application/json:
example: |
"No autorizado"

Queryparam me sirve para que me filtre además de por DNI por compañía.

TODO ESTO QUE HEMOS HECHO HASTA AQUÍ HAY QUE HACERLOS POR CAJAS

EJERCICIO:

Vamos a hacer:

Un RAML con:

versión 1.

Titulo hola demo

Base URI la de local host..

Descripcion

Un único recurso que se va a llamar: log in, este log in va a tener una descripción
Queryparameters: user y password y estos llevarán las propiedades anteriores. El usuario va a
ser requerido y el password no.

Respuestas contempladas: 200 y un mensaje que me diga que todo ha ido perfe. También la
respuesta 400 que me diga que me he equivocado en la respuesta, el 401 y 500 (mirar tabla).

#%RAML 1.0
title: demo1
baseUri: http://localhost:8081/api
description: api de ejemplo

/Persona:
description: recurso Persona
/Paciente:
get: #para extraer datos del paciente uso el método get
#usamos un metodo get para listar todos los pacientes
queryParameters:
nombre: #es un queryparameter y escribo sus props
displayName: Nombre #como quiero que aparezca en mi consola
type: string
description: nombre del susuario
required: true
example: Nely #con esto le hago ver el campo que tiene que
meter, le aparEcerá el nombre pero él puede cambiarlo por el suyo, esto
es util para por ejemplo la est de fechas
apellido:
displayName: Apellido
type: string
description: apellido del usuario
responses:
200:
body:
pplication/json:
example: |
"Todo ha ido bien"
401:
body:
application/json:
example: |
"No autorizado"
/{DNI}:
get: #para extraer datos del paciente uso el método get
#usamos un metodo get para listar todos los pacientes
responses:
200:
body:
application/json:
example: |
"Todo ha ido bien"
401:
body:
application/json:
example: |
"No autorizado"

post:
responses:
200:
body:
application/json:
example: |
"Todo ha ido bien"

401:
body:
application/json:
example: |
"No autorizado"

put:
responses:
200:
body:
application/json:
example: |
"Todo ha ido bien"
401:
body:
application/json:
example: |
"No autorizado"

/Medico:

EJERCICIO EN ANYPOINT STUDIO -> ESTAMOS HACIENDO LO QUE APARECE VISUALMENTE

En este ejercicio solo estamos haciendo por RAML la parte visual. Normalmente a partir de la
parte visual vamos a hacer el flujo. El cliente por tanto tiene que darlo todo super claro
porque primero haré la parte de diseño y después ya le vamos añadiendo la funcionalidad a
ese diseño. Aquí como no tiene ninguna funcionalidad hecha (no hay un runtime hecho con
sus cajitas) si le doy a get no va a pasar nada.
#%RAML 1.0
version: 1.0
title: holaDemo
baseUri: http://localhost:8081/api
description: API para meter usuario y contraseña

/Login:
description: Meter el usuario y contraseña
get:
queryParameters:
user:
displayName: Introduce tu usuario
type: string
description: nombre del usuario
required: true
example: María #Esto a él le aparece tal cual y así sabe
como tiene que meter su nombre, Él puede cambiarlo
password:
displayName: Password
type: string
description: contraseña asociada al usuario
required: false
example: $$$$$ #Así el usuario ve un ejemplo de como es la
contraseña
responses:
200:
body:
application/json:
example:
{"code return" : "OK"}
400:
body:
application/json:
example:
{"code return" : "Solicitud fallida"}
401:
body:
application/json:
example:
{"code return" : "No autorizado"}
500:
body:
application/json:
example:
{"code return" : "Error en el servidor"}

BUILDING APIs:

Estructura del mensaje:

Lo importante es el payload, donde está la chicha. Hay otras cosas que me enriquecen el
mensaje, me dan info. Ejemplo un inbound property (que es un queryparam), uriparam,
header, … Para acceder a estar propiedades tenemos que picar código.

Para acceder tendríamos que:

Para acceder al queryparam que es el usuario en mi ejemplo anterior tendría que escribir:

Con esto accederíamos al campo user:

message,inboundProperties.'http.query.params'.user
(*Inbound son propiedades de la entrada*)

Si queremos acceder a
message.outboundProperties.xxx

el outbund son propiedades de salida, por ejemplo sería cuando el tío cambia el nombre.
Puede ser modificado durante el flujo, o no.

En el body además de lo que hay quiero adjuntarle un documento, esto es un attachement.


Escribiría:

Message.attachement

APIKitRouter:

Es necesario para mi API, es un nodo dentro de mi flujo. Siempre va detrás del http inicial.
Gracias a este nodo configuro donde quiero que se vaya cuando alguien haga la acción en la
consola. Cuando el tío le da a POST, se ejecuta el nodo POST gracias a esto. Es un
ENROUTADOR.

Todo enroutamiento dentro del APIKit le podemos aplicar una política de seguridad. Es muy
importante por esto, para poder securizar.

El APIKitConsole lleva la misma información que el APIKitRouter, van enlazados. PERO es la


parte visual. El APIKitConsole se rellena automáticamente con el Router, yo no lo tengo que
hacer. Si no quiero una consola no tengo que poner esta consola.

CREACION EN ANYPOINT DE FLUJOS:

Busco en la paleta Flow, arrastro el icono y le cambio el nombre. Añado de la paleta maping
exception estrategy como otro flujo y después un reference exception Strategy dentro del
primer flujo, de manera que cuando haya un error va a venir ahí y eso hará referencia a la caja
de referencia donde los errores estarán mapeados (le saldrá al cliente por pantalla que ha
habido el error por ejemplo 200). Dentro de la caja mapping irán todas nuestras excepciones y
para cada excepción haré otra caja (cogida de la paleta como exception maping). Cada cajita le
pongo un nombre (ejemplo: 401, 400,…).

Mule sabe que son excepciones pero no sabe como tratarlas. Yo le digo que haga uso de un
módulo de Mule añadiendo este enlace en el más verde A CADA CAJA:
org.mule.module.apikit.exception.NotFoundException
ESTO SIEMPRE ES ASÍ.

Cajita401: quiero a conciencia que muestre un mensaje que yo escribo. HAGO siempre esto:

Arrastro de la paleta Property. Y ahí le digo que voy a meter un json como aparece:
Para poder escribir lo que yo quiero arrastrar un Set payload despues de Property y escribo lo
que veo en la anterior pantalla TAL CUAL PARA TODAS LAS CAJAS.

Después en Set Payload escribo en formato json lo que quiero que aparezca tal cual. Escribiría:
[{“code return”:”blablablá”}]

Creo otro flujo que va a ser mi consola. Hago en ambos flujos los HTTP iniciales. El de la
consola se va a hacer como el primero pero en el Path pongo /console/* (el asterisco significa
lo que sigue). En el flujo normal pondría /api/*. Pongo eso porque en mi RAML en baseUri he
puesto: http://localhost:8081/api

En los allowed methods si solo voy a usar un GET o PUT lo escribo, si voy a usar más lo dejo
vacío.

En main (en el flujo main) solo meto el http y el router.

Hago otro flujo debajo de la consola para las variables. Arrastro a la parte process de este flujo
una Variable de la paleta.
Le doy a Set variable, le doy un nombre (usuario) y en el Value pongo lo que va a contener que
es el user de mi RAML y pondría así: #[message.inboundProperties.'http.query.params'.user]

Esto ahora mismo aparecerá vacío y hasta que el tío no escriba algo en la consola no se me
rellena. Si quiero que siempre aparezca lo mismo lo escribiría yo tal cual en la casilla en vez de
lo de antes.

Si ahora quiero que me muestre por pantalla Hola Pepito tengo que arrastrar detrás del flujo
Variable, un Set Payload.
Lo que hicimos para el movil fue subir a RUNTIME pero con el API manager no hicimos nada.

HACER EL API MANAGER -> SUBIR A MI CLOUD


En un proyecto API tengo que tener en el RUNTIME mi proyecto .zip desplegado pero en el API
manager también tengo que tener subido el RAML para tenerlo securizado. Lo desplegamos
metiendonos en Runtime, le damos a deploy, busco mi archivo zip y cambio la version.

(*Yo ya lo tengo en el cloud (tiene una URL) porque me pude meter desde el movil PERO si lo
quiero securizar tengo que desplegarlo en el API manager. Si el cliente no me lo pide le paso la
URL y punto*).

Ahora en el web cloud:

En una versión: (ejemplo versión 1.0.0) el digito de más a la derecha se aumenta cuando yo
hago algún cambio de código, cuando es un minor change (cuando cambio una tontería). El del
medio es cuando cambio algo más importante pero no la funcionalidad. Por ejemplo le añado
una response más para que muestre por pantalla. El número de la izquierda cambia cuando el
cambio realizado es importante. Esto se llama control de cambios, control de versiones. Uno
sube a un repositorio el cambio del código, si otra persona ha modificado algo también lo sube
y esta tool lo fusiona todo y aclara.

Asset versión lo pone mule, no es mi versión.

Le damos al design manager y le damos a create y copiamos y pegamos el RAML. Si hemos


creado algún archivo en anypoint como complemento tenemos que crearlo también. Le damos
a publish (en el icono del infinito).

Ahora nos vamos a API manager, y ponemos en el nombre el nombre que le hemos dado antes
en el design manager. Estamos metiendo en mi propio cloud (change) de mule, mi RAML.

Esto tenemos que enlazarlo con mi RUNTIME del otro día para que MULESOFT me haga un
único proyecto nuestra API de ahora con lo de las cajitas del anypoint (programa).

Nuestro .zip lleva el RAML y las cajitas. El RAML y las cajitas los tengo contenidos en el
RUNTIME que me genera una URL. Aquí lo tengo todo PERO la seguridad se aplica solo a la
parte visual porque es lo que es lo que cualquier tío ve fuera.

El API MANAGER lo uso si el cliente pide seguridad (además se usa para estadísticas y eso pero
nosotros sobre todo hacemos la API manager para crear políticas de seguridad).

Cuando en el API MANAGER tengo mi RAML desplegado, esta API pasa a ser la principal de mi
proyecto, ya no la del .zip. Si solo quiero tenerla en mi RUNTIME, como consola como el otro
día, ese .zip es el principal.

Al final, donde pone implementation URL, es donde vamos a enlazar: si yo he puesto en el


anypoint studio /api/* aquí tengo que poner mi URL (que me genera el runtime aquí mi
proyecto aparece con el nombre del zip, no el que le he puesto) seguida de /api.
Cuando se ha creado MI API MANAGER, pulsamos en la versión y nos sale sus características.
Vamos a hacerle un proxy desde aquí. Este es necesario para enlazar API MANAGER Y
RUNTIME MANAGER. Siempre que hagamos algo con API MANAGER hay que meterle un proxy.

Para ello miramos debajo en API configuration, le damos a Endpoint with proxy y lo demás lo
dejamos igual. En advanced options lo dejamos todo igual y clicamos el tick. Le damos a save y
se nos despliega para configurar el proxy.

Se le pone un nombre que es el nombre final que le doy al cliente, no puede ser igual al del .zip
desplegado del RUNTIME. Ponemos la versión del RUNTIME (era 3.8. algo) y le damos a deploy.
Después debe aparecer una barrita que pase de naranja a verde.

Si me voy a RUNTIME ya me aparece (se ha creado un archivo proxy con la palabra Gateway y
si cojo esa URL, copio y pego en un navegador y le añado /console puedo probarla. Ahora toda
modificación que yo haga en mi RAML se me cambiará en la API MANAGER porque ahora esta
es la principal (es la que tiene seguridad).

Si quiero modificar mi RAML, una vez he hecho el cambio, tengo que desplegar por partes otra
vez la API: publicarla en mi echage. Una vez he cambiado lo que sea en mi RAML, le doy a
guardar y a mi símbolo infinitio.

Ahora nos metemos en el API MANAGER, nos metemos en nuestra API. Le damos a action y a
change especification y cambiamos la versión. Proxy sin embargo no tenemos que desplegarla
de nuevo.

SOLO SE REDESPLIEGA EL PROXY CUANDO NUESTRA URL INTERNA (NUESTRO HTTP) HAYA
QUE ASIGANARLA A OTRO PROYECTO O CUANDO NUESTRA URL CAMBIA POR CUALQUIER
MOTIVO. CON CAMBIOS DEL RAML,… NO HACE FALTA, MULE ENLAZA DIRECTAMENTE EL API
MANAGER CON EL RUNTIME.

EN ANY POINT: LOS FLUJOS-CAJITAS SE HACEN AUTOMÁTICAMENTE A PARTIR DE MI RAML. ES


DECIR, YO HAGO MI RAML Y EN LA CARPETA QUE SE CREA MI PROYECTO PULSO BOTON
DERECHO Y LE DOY A GENERAR FLUJOS Y SE ME CREA TODO AUTOMÁTICAMENTE. TENEMOS
QUE REVISAR LAS EXCEPCIONES POR SI SE HA COMIDO ALGO, CAMBIARLE LOS NOMBRES QUE
SE HAN CREADO AUTOMÁTICAMENTE POR LOS MÍOS Y EN EL CASO DE NUESTRO EJEMPLO
PONER LO DE VARIABLE DELANTE DE PAYLOAD. AL CAMBIAR LOS NOMBRES A LOS FLUJOS,
TODO LO QUE ESTÉ REFERENCIADO TENGO QUE HACER QUE REFERENCIE AHORA AL NOMBRE
QUE YO HE PUESTO (EJEMPLO EN LAS EXCEPCIONES O EN EL KITROUTER)

EJERCICIO PARA CONECTAR CON UNA BASE DE DATOS

Vamos a poner un derby porque no tenemos un SQL.

Buscamos en la lupa y ponemos cmd (command Prompt – java) que es la consola de mi PC.

Aquí podemos llegar a archivos de nuestro pc. Para ir hacia atrás le damos a espacio, cd ..,
intro.

Cuando llegamos a C: pegamos el link de la carpeta que queremos buscar. Después escribo: dir
y me sale el contenido que hay en mi carpeta.
Después pego el archivo.jar de derby (no sé bien qué es).

EJERCICIO PARA FILTRAR EN LISTA DE VUELOS POR ID EN ANYPOINT

He creado un flujo con su HTTP listener, un data base (en el que de alguna manera he enlazado
con el del friki de manera rara porque no era por sql y que ella lo ha hecho siguiendo una guía)
y un object to jason (que no tocamos). En el http en el Path tenemos que meter algo como:
/BD.

Creo un segundo flujo que cambio el nombre y cuyo puerto cambio. Dos http LISTENER no
pueden tener mismo puerto, así que le pongo 8082.

En el database selecciono la operación select y escribo:


SELECT * FROM american WHERE
ID=#[message.inboundProperties.'http.uri.params'.ID]

En el path de este http pongo:

Como es un uriparam lo pongo entre llaves. (en la URL pongo el número directamente que
quiero que filtre tras una barra (así lo probaría en Postman)

El uriparam lo metemos en una variable y en el select en vez de poner todo vamos a hacer
referencia a la variable.

Para ello arrastramos de la paleta tras el http una Variable, cuyo valor que le ponemos será:
#[message.inboundProperties.'http.uri.params'.TOAIRPORT] TOAIRPORT es el recurso que el friki le ha
puesto. A esta variable yo le pongo el nombre que quiera, en este caso destination.

En el database ahora, hago referencia a la variable de esta manera:

SELECT * FROM american WHERE TOAIRPORT=#[flowVars.destination]

DEBUGAR
Debugar es ver lo que está pasando en cada nodo para ver errores posibles.
EJERCICIO CON POST

Hacer una API (tendrá por tanto raml) en el manager y un .zip. La API tendrá un recurso
login, el método será un post, le añadimos a la API toda la información necesaria. En el body
del método post metemos un esquema (en vez de example), este esquema nos lo da ella.
Este esquema no dice nada, solo da la estructura. Quiero que al usuario le salga por pantalla
además un ejemplo de lo que tiene que meter. Viendo ese esquema entenderemos el
ejemplo que le tenemos que decir al jipi que tiene que meter. Este ejemplo tenemos que
incluirlo como .json, lo vamos a incluir y no escribir nosotros mismos.

Respuestas posibles contempladas: 200, donde se presenta el mensaje al cliente, el 400, 401,
405, 415, 406 y 500.

Después del RAML hacer el flujo.

Tenemos que desplegarlo en la nube e interactuar con nuestro móvil.

ORDEN QUE SIEMPRE HAY QUE SEGUIR:

Método, parámetro, body, mediatype, esquema en caso de que lo haya y ejemplo en caso de
que lo haya

SCHEMA VS EJEMPLO

Un esquema es un código el cual sirve para validar un ejemplo que el usuario meta por
pantalla. Dentro del esquema tengo que definir que todo username es un string, que es
requerido y le voy a dar una longitud (un max y un min). ESQUEMA = VALIDACIÓN DE DATOS
DE ENTRADA.

RAML del anterior ejercicio:


#%RAML 1.0
title: demo2
baseUri: http://localhost:8081/api
description: api con POST

/Login:
post:
body:
application/json:
schema: |
{
"type": "object",
"$schema": "http://json-schema.org/draft-03/schema",
"id": "http://jsonschema.net",
"required": true,
"description": "Authentication Credentials",
"properties": {
"username": {
"type": "string",
"required": true,
"minLength": 4,
"maxLength": 20
},
"password": {
"type": "string",
"required": true,
"minLength": 4,
"maxLength": 30
}
}
}
example: !include complemento/ejemploejerciciopost.json
responses:
400:
body:
application/json:
example: |
{"respuesta" : "Solicitud fallida"}
401:
body:
application/json:
example: |
{"respuesta" : "No autorizado"}
405:
body:
application/json:
example: |
{"respuesta" : "No autorizado"}
415:
body:
application/json:
example: |
{"respuesta" : "Tipo de medio no soportado"}
406:
body:
application/json:
example: |
{"respuesta" : "No aceptable"}
500:
body:
application/json:
example: |
{"respuesta" : "Error en el servidor"}

Para generar los flujos desde el RAML: en el fondo del mismo raml pulsar botón derecho y
generar mule Flow. Hacer los cambios de redirecciones y nombres.

Dentro del RAML vamos a hacer cambios para hacer el código más simple. Para ello vamos
haciendo archivos (files) donde pegamos el esquema, que después en el RAML llamaré (con
!include ….). También las responses las copio y pego y las meto en un nuevo archivo RAML. A
este también haré referencia. (VER DEBAJO).

SUBFLUJOS

Vamos a almacenar en una variable el usuario y dependiendo del valor del usuario hacemos un
if (nodo choice). Si lo que tiene mi usuario es igual a Nely entonces lanzo por consola un
mensaje que diga bienvenida Nely. Si no aparece Nely, quiero que además de que me diga el
mensaje lo siento pero no puedes acceder al login, quiero que el http status code cambie a un
401 y para eso tenemos que setear una propiedad del mensaje.

Para modificar el valor de un status de error ponemos un Property, le ponemos en Name


http.status y en value ponemos directamente 401 (o lo que sea)

Para hacer un subflujo, creo un subflujo debajo, lo llamo condicional y le meto todo el choice.
Hago un flowreference dentro del flujo anterior y hago referencia al flujo condicional. Así creo
un subflujo.
DATATYPE
En un get voy a meter un acceso a mi lista de objetos.
type: object
properties:
ID?: integer #es una clave primaria, por eso lleva ?, porque es potencialmente filtrable
code: string
price: number
departureDate: string
origin: string
destination: string
emptySeats: integer
plane:
type: object
required: false
properties:
type: string
totalSeats: integer

¿Cómo metemos en un RAML un datatype?


types:
AmericanFlight: !include AmericanFlightDataType.raml

Dentro de ese anterior raml es donde tengo el texto de arriba (en ese raml tengo la
cabecera: #%RAML 1.0 DataType para decir que es un datatype, como hicimos con trait).

Hacemos una api con traits con un unico recurso flights y vamos a tener la posibilidad
de filtrar por un uriparam. El recurso flights va a tener un queryparam llamado
destination (va a ser requerido). El destination va a ser una enumeración de datos:
SFO, LAX y CLE. Quiero que vea los distintos tipos de respuesta que nos puede devolver
cada uno de los métodos. El recurso flight va a poder jugar con get y post. En el post
metería un esquema para poder validar que la info que mete el cliente en un vuelo es
correcta. Voy a poder filtrar el uriparam con get, delete y put y quiero que el cliente
vea por pantalla lo que él puede utilizar para usar estos métodos. Para el delete no
hace falta body y para el put sí hace falta body porque para actualizar algo, que es
meter info, tengo que hacer un body.
#%RAML 1.0
title: ejerciciocomplejo
version: v1
baseUri: http://localhost:8081/api

traits:
excepciones: !include traits/exceptionstraits.raml
excepciones2: !include traits/exceptionstrait2.raml

types:
AmericanFlight: !include dataTypes/AmericanFlightDataType.raml
modoesquema: !include schemes/schema.json
/flights:
get:
queryParameters:
destination:
required: true
enum:
- SFO
- LAX
- CLE
body:
application/json:
responses:
200:
body:
application/json:
type: AmericanFlight[]
is: [excepciones2]
post:
body:
application/json:
schema:
type: AmericanFlight
example: !include ejemplos/ejemplo.json
responses:
is: [excepciones]

/{ID}:
get:
body:
application/json:
responses:
200:
body:
application/json:
type: AmericanFlight[]
is: [excepciones2]
put:
body:
application/json:
type: AmericanFlight
example: !include ejemplos/ejemplo.json
responses:
200:
body:
application/json:
example: |
{
"http.status:" : "El vuelo ha sido actualizado con
exito"
}
is: [excepciones2]
delete:
body:
application/json:
responses:
200:
body:
application/json:
example: |
{
"http.status: " : "El vuelo ha sido borrado
correctamente"
}
is: [excepciones2]

Todo método lleva un:


body:
Application/json:
TYPE SOLO PUEDO PONERLO EN PUT Y EN POST NO EN GET Y DELETE. EN ELLOS IRÁ
DENTRO DE LAS RESPONSES.

Una vez hecho mi raml genero mis flujos. les cambio los nombres, veo que los http están
bien y sus paths.
Ahora enlazo al kit router los flujos que he hecho. (dándole al + verdecito).
Configuro en mi flujo get un http. le doy al + y añado la URL de los datos del cliente. (el
(host, port y Path de su URL). Fuera ya de la configuración del HTTP (del + verdecito)
añado
Todo lo que vaya en mi url lo configuro en el http. Como bath ponemos el recurso
(/flights).
En el recurso get vamos a hacer que al cliente le aparezca por pantalla la lista de vuelos
según lo que haya elegido (LAX, CLE o SFO). Cuando el cliente elige, tengo que coger lo
que ha elegido y almacenarlo en una variable para poder ahora filtrar en la lista de todos
los vuelos.
Para ello arrastro delante de mi HTTP una VARIABLE, que recogerá ese valor (en mi caso
decisióncliente).
En HTTP se FILTRA ASÍ: le damos a Add Parameters, en tipo query, añadimos en el Value
el nombre del query, en este caso destination y el value escribiríamos
#[flowVars.decisionCliente].

SECURIZACIÓN DE UNA API


Nos metemos en el API manager dentro de nuestra API (pulsando el v1). Le damos a
policies y a apply new policy (aplicar política).
Para aplicar política necesitamos haber rhecho:
-Que nuestros estén cambiados de nombre
-que estos nombres esten declarados en el apikit router
-que en el cloud tengamos generado un proxy ente el API manager y el RUNTIME
manager
Dentro del Apply New Policy nos aparecen distintas políticas. Nosotros usamos la de
client_ID enforcement y pulsamos el botón azul.
Está política requiere actualizar el raml definition. Además necesitamos client_id y
client_secret. Estos son queryparams en raml y por tanto estaría cambiando mi raml
pero también los flujos (cajas).
Estos serían los query:
#[message.inboundProperties['http.query.params']['client_id']]
#[message.inboundProperties['http.query.params']['client_secret']]
Nosotros podemos aplicar la seguridad a lo que yo quiera, es decir si tengo más de un
recurso puedo aplicar la política o a todos los recursos o solo a uno específico. En mi
misma página donde estaba el here podemos elegir aplicarlo a todo o no.
Ahora en API specification snipper nos aparece lo que tenemos que añadir a nustro raml.
Nos vamos al design manager y metemos lo que viene a continuación.

traits:
- client-id-required:
queryParameters:
client_id:
type: string
client_secret:
type: string
/products:
get:
is: [client-id-required]
description: Gets a list of all the inventory products.

Lo que hay después de get tengo que ponerlo debajo de todos los gets que tenga en el
Proyecto.
Cambiar también en el raml la baseUri por el URL del zip desplegado (proxy)/api. Le
damos al infinito para publicar.
Nos vamos al APImanager y le cambiamos en la derecha en el botón action en Change
API specification la versión para poner la nueva que se ha creado al haber securizado.
Ahora hemos copiado y pegado el raml del design manager al anypoint (el programita).
Client_id y Client_secret son querys que vamos a meterle a los gets. En el raml no
tenemos que añadirle el query en sí porque en los traits ya están definidos y como en el
is: estamos poniéndole la privacidad pues perfe. En el flujo sin embargo sí vamos a tener
que añadir las conexiones externas client_id y client_secret. Para ello metemos en los
HTTP de los flujos get (ya que he aplicado la privacidad a todos ellos) queryparams con
Name: client_id
Value: #[message.inboundProperties['http.query.params']['client_id']]
Name: client_secret
Value: #[message.inboundProperties['http.query.params']['client_secret']]
Generamos un zip nuevo y ahora al desplegarlo no hace falta redesplegar el proxy
porque no hemos cambiado el URL del RUNTIME.
Este zip lo despliego no en el Gateway sino en el otro (el que es solo.zip). para eso pulso
sobre el archivito.zip y a la derecha le doy a choose file y elijo el nuevo .zip securizado.
Ahora me tengo que ir a API manager y meterme en mi proyecto (dándole a v1). Le doy
a redeploy y se me forma el proxy automáticamente a partir del nuevo.

TENGO QUE GENERAR LOS CLIENT_ID Y LOS CLIENT_SECRET:


Nos vamos al API MANAGER le damos a view API Exchange a al derecha de la pagina.
Ahora en los tres puntos de la derecha le damos a Request Access. Le damos a Create
new application, le ponemos el nombre que queramos y la URL que viene.
Se crea asi un client_id y un client_secret. Para verlo otra vez me meto en API manager
en Client Applications y a la derecha me salen.

APUNTES YOUTUBE
COSAS NUEVAS EN EMPRESA
Message Enricher: (las variables que quedan dentro de ese flujo no pueden salir), se acaban
perdiendo. Si me quiero quedar con algo de lo que se da dentro en la salida de este flujo
guardo lo que yo quiero seguir teniendo.

Session variable – record variable?

Mule Expression Language


(MEL)
MEL is a lightweight, Mule-specific expression language that you can use to
access and evaluate the data in the payload, properties and variables of a Mule
message. Accessible and usable from within virtually every message processor
in Mule, MEL enables you to quickly and elegantly filter, route, or otherwise act
upon the different parts of the Mule message object.

Prerequisites
This document assumes that you are familiar with Mule and its basic concepts.

Benefits of Using MEL


Use MEL instead of a scripting language such as Groovy, or a programming
language such as Java, to manipulate the contents of a message object. Using
MEL makes your application more consistent, and provides an efficient and
standardized method for evaluating expressions in Mule applications.

o MEL is an expression language that provides a consistent, standardized way for


developers to work with a Mule message’s payload, properties and variables.
o MEL makes use of Mule-specific context objects, you can code it with the help
of auto-complete
o Great tool for evaluating expressions in your flows
o Most importantly, MEL enforces consistency when accessing information in the
Mule message: rather than using multiple expression evaluators, you can use
MEL, the default expression evaluator, to consistently access and manipulate
information.
o MEL expressions work within message processors to modify the way the
processors act upon the message such as routing or filtering.
The example below demonstrates how you can use MEL to log the value of a
flow variable at runtime.

<logger message="The value in my first variable is #[flowVars.myVar1]" level="INFO"/>


An expression language, such as MEL, is similar, but not the same as, a scripting language: it
allows you to write short scripts that resolve dynamically to get values, set values, or perform an
operation on data. There is an overlap in functionality between an expression language and a
scripting language, but scripting languages are generally more useful if you are writing something
complex enough to require more than just a few lines of code, or if you need to include conditional
logic. If, however, you need to get or set values, invoke methods, or perform functions, you can do
so quickly and easily using an expression language.

Using MEL
Based on information Mule extracts from the message or its environment at
runtime, Mule evaluates expressions to complete three types of tasks:

o Extract information that it can use to process the current message; this can be
useful when set inside an expression component or expression transformer:
o #[payload]
o #[message.inboundProperties.'propertyName']
o #[payload.methodCall(parameters)]
o #[xpath3('//root/element1')]
o Evaluate conditions using the contents of the current message; this can be
extremely useful to filter messages from being processed:
o #[payload.age > 21]
o #[message.inboundProperties.'locale' == 'en_us']
o Define a target, other than the message payload, in which to store the result of
an expression evaluation; typically, this is helpful when set inside a message
enricher
o #[flowVars.output]

Shortcut for payload

Mule accepts the expression #[payload] as a shortcut for #[message.payload]. This shortcut only
applies to the payload field.

The following examples illustrate a few ways in which you can use MEL.

1. Use an expression to extract data to decide on a course of action based on the


contents, properties, or properties of a message. For example, a router (a.k.a.
flow control) can route purchase orders for different types of products to
different JMS queues. In the example below, a message carries information
about purchases from an online store which can be either a hardcopy book or
an mp3 file. The following code classifies the messages into different queues
based on the type of purchase.
2. <choice>
3. <when expression="#[payload.getPurchaseType() == 'book']">
4. <jms:outbound-endpoint queue="bookPurchases" />
5. </when>
6. <when expression="#[payload.getPurchaseType() == 'mp3']">
7. <jms:outbound-endpoint queue="songPurchases" />
8. </when>
</choice>

9. Use an expression to extract a value from the payload, properties, or context of


a message and its variables or attachments. For example, a connector might
extract a specific piece of information from the the current message to use as
an argument. In the example below, expressions extract information from a
message and pass each piece to the SMTP endpoint.

<smtp:outbound-endpoint from="#[flowVars.from]" to="#[flowVars.to]"


subject="#[payload.subjectLine]" responseTimeout="10000" doc:name="SMTP"/>

10. Use an expression to extract information, then use it to replace a token with an
actual value. For example, a logger can extract information from the payload
contents and place it into a logging message, as shown below.

<logger message="#[payload]" />

If the payload is an object and you can call a method to extract information, the
expression to extract may appear as follows.

<logger message="#[payload.getLoggingInformation()]" />

Expressions in Mule
It’s important to know that MEL has not always been the de facto expression
language Mule uses. Prior to version 3.3.0, expressions in Mule varied in syntax
according to their specific evaluator. Thus, although these expressions
supported a wide variety of functionality, the variation in syntax rules was time-
consuming to learn. This older style of expression was written in the
format: #[evaluator:expression]. A colon separated the evaluator from the
expression itself.

Mule 3.3.0 introduced Mule Expression Language (MEL), which implements a


single set of syntax rules that no longer contains an evaluator. The evaluator, by
default, is MEL itself, and it can interpret expressions formerly associated with
dozens of different evaluators. MEL expressions are written according to the
following format: #[expression]. Note the absence of the colon, which signals to
Mule that this is a MEL expression; thus Mule evaluates the expression using
MEL logic rather than the rules of a specific evaluator.

Note: Only use MEL expressions in your application.

Learning MEL
If you’re already familiar with Java, learning MEL is not difficult. That said, it’s
important to comprehend some Mule-specific details before you learn how to
apply MEL expressions in your application.
1. Understand the Mule message structure. Because you use MEL to act upon
the contents of a Mule message object (payload, properties and variables), you
first need to understand the basic structure of the message. If you are not
already familiar with it, read about the Mule message structure.
2. Understand how to see the contents of the Mule message. To be able to act
upon it, you need to be able to figure out what type of data the message
contains. Is the payload an array? Does the message contain a flow variable?
What inbound properties exist? The Mule Message Tutorialdescribes the tools
you can use to see inside the message, so that you know how to use MEL
expressions to manipulate the data.

After having absorbed this material, you are ready to begin learning about MEL
basic syntax, and start using expressions in your application.
ELEMENTOS DE MULESOFT

https://docs.mulesoft.com/mule-runtime/3.8/anypoint-
connectors

https://docs.mulesoft.com/mule-runtime/3.8/scopes

https://docs.mulesoft.com/mule-runtime/3.8/components

https://docs.mulesoft.com/mule-runtime/3.8/transformers

https://docs.mulesoft.com/mule-runtime/3.8/filters

https://docs.mulesoft.com/mule-runtime/3.8/routers

https://docs.mulesoft.com/mule-runtime/3.8/error-handling

https://docs.mulesoft.com/mule-runtime/3.8/anypoint-
enterprise-security

HTTP Listener: https://docs.mulesoft.com/mule-runtime/3.8/http-listener-connector

HTTP request: https://docs.mulesoft.com/mule-runtime/3.8/http-request-connector


https://docs.mulesoft.com/mule-runtime/3.8/async-scope-reference#configuration

https://docs.mulesoft.com/mule-runtime/3.8/cache-scope

https://docs.mulesoft.com/mule-runtime/3.8/foreach
https://docs.mulesoft.com/mule-runtime/3.8/flow-reference-component-reference

More about flows and subflows: https://docs.mulesoft.com/mule-runtime/3.8/flows-and-


subflows
https://docs.mulesoft.com/mule-runtime/3.8/logger-component-reference

https://docs.mulesoft.com/mule-runtime/3.8/groovy-component-reference

https://docs.mulesoft.com/mule-runtime/3.8/java-component-reference

https://docs.mulesoft.com/mule-runtime/3.8/javascript-component-reference

https://docs.mulesoft.com/mule-runtime/3.8/python-component-reference

https://docs.mulesoft.com/mule-runtime/3.8/ruby-component-reference

https://docs.mulesoft.com/mule-runtime/3.8/script-component-reference
https://docs.mulesoft.com/mule-runtime/3.8/rest-component-reference

https://docs.mulesoft.com/mule-runtime/3.8/cxf-component-reference

Script Transformers
https://docs.mulesoft.com/mule-runtime/3.8/script-transformer-reference

Java Object Transformers


https://docs.mulesoft.com/mule-runtime/3.8/transformers#common-transformer-
configuration-fields
Content Transformer

https://docs.mulesoft.com/mule-runtime/3.8/append-string-transformer-reference

https://docs.mulesoft.com/mule-runtime/3.8/expression-transformer-reference

https://docs.mulesoft.com/mule-runtime/3.8/xslt-transformer-reference

SAP Transformers
https://docs.mulesoft.com/mule-runtime/3.8/sap-connector

Message and Variable Transformers

https://docs.mulesoft.com/mule-runtime/3.8/property-transformer-reference
https://docs.mulesoft.com/mule-runtime/3.8/variable-transformer-referenceç

https://docs.mulesoft.com/mule-runtime/3.8/session-variable-transformer-reference
https://docs.mulesoft.com/mule-runtime/3.8/filters

https://docs.mulesoft.com/mule-runtime/3.8/choice-flow-control-reference

ETC…

Anda mungkin juga menyukai