Si buscamos un poco por Google encontraremos fácilmente que la opción más rápida y común es utilizar la XPath function boolean. Pero aquí veremos que no es así en todos los casos y que por tanto es mejorar contemplar más opciones.
<filter xpath="boolean($ctx:user)"> mediator+ </filter>
Dejemos claro también que si lo que queremos es validar query parameters y estamos usando una API, podremos hacerlo a través del atributo URL mappings pertinente. Y si lo que queremos es validar la request en una API podemos usar el mediator validate.
Pero supongamos que por motivos externos no podemos y necesitamos validar uno a uno dichos atributos o parámetros. Supongamos por tanto que nos llega un mensaje JSON con un atributo denominado user. Y presupongamos también que obtenemos ese atributo y lo almacenamos en la propiedad de contexto user:
<property name="user" expression="json-eval($.user)" scope="default" type="STRING"/>
El primer caso práctico será probar que pasa cuando enviamos un valor o no asociado al atributo. Y como se comporta la función boolean.
1. Si enviamos {"user":""}. Funcionará correctamente y la expresión XPath devolverá false. Por lo que podremos realizar la validación correctamente.
2. Si enviamos el payload vacío {}. También funcionará correctamente, puesto que la expresión XPath devolverá false.
3. ¿Pero qué pasa si enviamos el payload {"user:null}. La expresión XPath también debería devolver false, puesto que el atributo es nulo. Pero he aquí que en contra de lo en aparente, el resultado de la función será true.
Si intentamos cambiar la validación de boolean($ctx:user) por string($ctx:user) != ''. No tendremos ningún avance puesto que funcionará exactamente igual.
Para poder corregir esta casuística deberemos realizar la siguiente validación:
<filter xpath="boolean($ctx:user) and string($ctx:user) != 'null'"> mediator+ </filter>
En principio con estas dos funciones tendríamos las distintas casuísticas. Para terminar un par de detalles.
1. Cuando queremos almacenar el valor de un atributo o parámetro de la request podemos indicar que tipo de objeto es: String, Integer, etc. Hay que tener cuidado con esto siempre que no se elija String, porque si el el campo es vacío o nulo puede fallar la lógica al intentar convertirlo.
2. Puede ser un poco engorroso la validación manual si tenemos muchos atributos. Para ello podemos crearnos nuestro propio template, que nos ayude a evitar duplicar código. Aquí os pongo un simple ejemplo:
<template name="validate"> <parameter name="field"/> <parameter name="text"/> <sequence> <filter xpath="boolean($func:field) and string($func:field) != 'null'"> <then/> <else> <payloadFactory media-type="json"> <format>{"code":400, "exception":"message not valid","detail":"$1"}</format> <args> <arg evaluator="xml" expression="$func:text" literal="false"/> </args> </payloadFactory> <property name="HTTP_SC" scope="axis2" type="STRING" value="400"/> <property name="messageType" scope="axis2" type="STRING" value="application/json"/> <respond/> </else> </filter> </sequence> </template>
Y podemos invocarlo de la siguiente manera:
<property name="user" expression="json-eval($.user)" scope="default" type="STRING"/> <call-template target="validate"> <with-param name="field" value="{$ctx:user}"/> <with-param name="text" value="user doesnt exist"/> </call-template>
No hay comentarios:
Publicar un comentario