Ya estuvimos hablando en un post anterior de WSO2 y el cache mediator. Hoy veremos una solución alternativa pero similar. En este caso utilizaremos Redis, que nos permitirá cachear la respuesta de un backend.
Redis es un almacén de estructura de datos de valores de clave en memoria rápido y de código abierto. Básicamente una base de datos nosql de tipo clave y valor, muy popular entre los desarrolladores. Redis, permite el uso de diferentes tipos de datos: List, Sets, Hashes, etc.
Nosotros nos basaremos únicamente en los pares clave-valor, los hashes. Y veremos su uso a través de un ejemplo, como siempre. En este ejemplo llamaremos a un backend y almacenaremos su respuesta asociado al identificador del objeto. Lo cual nos permitirá que al volver a llamar con el mismo identificador, devolver la respuesta anteriormente obtenida.
Para empezar, usaremos un WSO2 EI 6.5.0. Con la versión standalone no es posible conectarse a Redis, para conseguirlo debemos hacer dos cosas:
- Añadir la librería Jedis (2.10.2) en la carpeta ${WSO2_HOME}/lib y arrancar el servidor.
- Añadir el conector de Redis a través de la interfaz gráfica.
El conector se puede obtener desde el WSO2 Store, y hay distintas versiones en función del producto que utilicemos. Hay que recordar que una vez después de añadirlo es necesario habilitarlo.
docker run -p 6379:6379 --name redis -d redis
- Buscamos el identificador en Redis a través de la operación hExists. En la cual tenemos que incluir el volumen donde esta almacenado y su clave.
- Si existe la clave, utilizaremos la operación hGet con los mismos valores para recuperar el valor almacenado.
- Si no existe la clave, procederemos a llamar al backend. Posteriormente almacenaremos el valor a través de la operación hSet, en la cual indicaremos el volumen, la clave y el valor asociado.
- La primera vez que utilicemos el conector debemos invocar la operación init, la cual nos posibilitará la conexión a Redis.
- El resultado de la operación hExists se almacena en una propiedad de contexto denominada redisResponse.
- La operación hGet devuelve un valor true o false en base a si encuentra o no el resultado.
- Debemos almacenar y restaurar el payload al utilizar la operación hSet para evitar devolver el resultado de la misma al cliente.
<resource methods="GET" uri-template="/{bookId}"> <inSequence> <property name="bookId" expression="$ctx:uri.var.bookId"/> <redis.init> <redisHost>localhost</redisHost> <redisPort>6379</redisPort> <redisTimeout>500</redisTimeout> </redis.init> <redis.hExists> <redisKey>Library</redisKey> <redisField>{$ctx:bookId}</redisField> </redis.hExists> <filter source="$ctx:redisResponse" regex="true"> <then> <redis.hGet> <redisKey>Library</redisKey> <redisField>{$ctx:bookId}</redisField> </redis.hGet> </then> <else> <call> <endpoint> <http method="GET" uri-template="http://localhost:57001/book/{uri.var.bookId}"/> </endpoint> </call> <enrich> <source type="body" clone="false"/> <target type="property" property="ORIGINAL_PAYLOAD"/> </enrich> <redis.hSet> <redisKey>Library</redisKey> <redisField>{$ctx:bookId}</redisField> <redisValue>{$ctx:ORIGINAL_PAYLOAD}</redisValue> </redis.hSet> <enrich> <source type="property" clone="false" property="ORIGINAL_PAYLOAD"/> <target type="body"/> </enrich> </else> </filter>
<property name="ContentType" scope="axis2" type="STRING" value="application/json"/> <respond/> </inSequence> </resource>
<resource methods="DELETE" uri-template="/{bookId}"> <inSequence> <property name="bookId" expression="$ctx:uri.var.bookId"/> <redis.init> <redisHost>localhost</redisHost> <redisPort>6379</redisPort> <redisTimeout>500</redisTimeout> </redis.init> <redis.hDel> <redisKey>Library</redisKey> <redisFields>{$ctx:bookId}</redisFields> </redis.hDel> <respond/> </inSequence> <outSequence/> <faultSequence/> </resource>
No hay comentarios:
Publicar un comentario