Vimos en las entradas anteriores sobre el uso de oData en Salesforce con Connect, pero dejé para más adelante el Apex Connector Framework (ACF), y ha llegado la hora.
Con un caso de uso que espero entretenido e interesante, muestro como el ACF nos abre un fácil integración con sistemas externos que sin él tendría un coste muy elevado, abriendo las capacidades internas de Salesforce Connect.
Si no conoces el ACF, no te preocupes, realizaré una pequeña introducción, y si lo conoces, quizás te intereses saber algo más de criptomonedas 😉
Caso de Uso
Me llama la atención el revuelo de las criptomonedas, oigo que su fluctuación es muy alta, que son muy costosas, por eso quiero analizarlas.
Quiero conectarme desde mi ORG a un sistema externo, que me proporcione información completa sobre ellas y así realizar un análisis y seguimiento.
Es decir:
- Quiero ver la información de las criptomonedas más importantes existentes, ordenar por % de fluctuación última hora/diaria/semanal, valor de cotización por unidad, etc.
- Además como estoy más familiarizado con € que con $ Dólares, quiero la transformación de su cotización de USD a EUR de forma transparente.
- Esta cotización la quiero rabiosamente actualizada y procedente del Banco Central Europeo (BCE), que es la que uso en mi casa, para negociar cuantos Dipper se compran mis hijos 🙂
- Finalmente, quiero relacionar la información de las criptomonedas con otro objeto que tengo que llamo Valoraciones.
- En este objeto mantengo anotaciones y comentarios de seguimiento de alguna criptomoneda que considero interesante y utilizo un Rating estándar en la industria con los valores: No Mola, Mola, Mola Mazo que me sirve para hacer clasificar las más interesantes.
Para llevar a cabo estos requerimientos tengo los siguientes proveedores de información:
- El BCE proporciona un servicio API que devuelve el tipo de cambio de varias monedas internacionales respecto al Euro en formato XML
- coinmarketcap.com proporciona una API que devuelve la cotización de las criptomonedas en formato JSON con múltiples posibilidades
Restricciones: es muy importante notar, que ambos servicios establecen unos criterios de uso de sus datos muy restringidos
Estas restricciones son:
- Únicamente se permite la consulta
- No se permite el almacenamiento de los datos
- No se permite la divulgación con terceros
Este escenario, aunque te pueda parecer ajeno, estoy seguro que si realizas una analogía con sistemas empresariales, a los cuales, la legislación les aplica restricciones copia de datos sensibles, impidiendo que se puedan duplicar, y además controlar el acceso, pero que necesites usar en una ORG, verás que tiene una aplicabilidad creciente.
Diseño de Alto Nivel de la solución
Cualquiera de nosotros seguro que piensa en primera instancia en solucionar este escenario vía integraciones mediante callouts, como por ejemplo:
- Construir varias callouts que alimenten sendos Custom Objects donde se almacene la cotización de las criptomonedas y de la cotización del €-$, para realizar cruces y cálculos y relaciones con el objeto Valoraciones.
- Son varias callouts, porque como mínimo tengo que acceder a una API del BCE para obtener el cambio de moneda y a otra API para acceder a la cotización de las criptomonedas
Pero las restricciones impuestas sobre la copia de los datos, nos limita el uso de este sistema de integración, ya que sin almacenar datos, nos podemos construir Custom Objects con los que relacionar, realizar reporting, etc.
Afortunadamente, tenemos una muy buena alternativa: el uso de Salesforce Connect con el Apex Connector Framework.
Conceptos Básicos del Apex Connector Framework
El Apex Connector Framework, está ligado a Salesforce Connect y es la solución ante la problemática siguiente: Queremos utilizar Salesforce Connect para acceder a una fuente de datos (sea una base de datos o cualquier fuente de datos), pero que no publica sus datos en formato/protocolo oData.
Si el APC, debemos optar por buscar conectores de terceros como vimos en el artículo anterior, que nos ofrezcan esta connectividad, algunos de los más conocidos en el mercado son Skyvia, Progress, cData, etc. Pero si la fuente de datos, es una fuente totalmente heterogénea, procedente de un sistema propio, etc., para que lo que no podemos o no queramos usar un conector estándar, inicialmente estaríamos limitados a no poder usar Salesforce Connect.
Para ello, el APC, como solución nativa de la plataforma, nos ofrece la posibilidad de implementar nuestras propias funciones y proporcionar a Salesforce Connect la información en el formato requerido como si de una fuente Odata nativa se tratara.
Esto nos permite dar respuesta al escenario propuesto:
- Obtener la información de las criptomonedas y usarla con un Custom Object (de hecho será específicamente un External Object)
- Realizar la conversión a Euros en el mismo momento que obtenemos la información de las monedas, por lo que podremos satisfacer el requerimiento de realizar el cambio más reciente posible
- No habrá almacenamiento de datos, y por tanto, estaré respetando las restricciones de contrato impuestas con mis fuentes de datos
- Ahorro cierto Data Storage, aunque es poco (en un caso de uso donde quisiera replicar todo el catálogo de productos, u otras entidads de cierto tamaño este punto sería más importante)
En detalle:
- Me aparecerá disponible la creación de una External Data Source como si se ofreciera en protocolo oData
- Cuando hago click en Validate and Sync obtendré los objetos que nosotros hayamos indicado y con los campos indicados
- Los resultados de la consulta sobre esos objetos, serán aquellos que nuestro cñodigo devuelva, y tan solo con adecuarnos a unas estructuras de datos y clases concretas (para que así Salesforce Connect las entienda y trate como si fueran procedentes de oData)
- Es decir, cuando el usuario lanza una Query sobre esos objetos, en lugar de lanzar una consulta con el protocolo oData, se ejecutará nuestro código que devolverá los resultados como si provinieran de una fuente oData nativa

Esto, que podría ser muy complicado, está muy simplificado gracias a que el APC ofrece todas las clases y la documentación necesaria para llevarlo a cabo.
De esta manera, la combinación de Salesforce Connect con el Apex Connector Framework nos permite acceder a fuentes de datos externas, de cualquier naturaleza en cualquier sistema, y que no se ofrecen como oData sinó como interfaces, manteniendo las capacidades de Salesforce Connect, el uso de External Objects, external/internal lookups, reporting, etc.
Como dije esta opción requiere de programación Apex, y cuantas más funcionalidades necesitemos, más cantidad de código deberemos desarrollar:
- para filtrar resultados (permitir realizar filtros de los datos)
- paginar resultados cuando son muy voluminosos
- permitir consultar SOSL
- permitir (UPDATE) actualizar los datos en la fuente de datos desde Salesforce
- permitir (DELETE) borrado de datos en la fuente de datos desde Salesforce
- etc.
Cuando veas el código de la clase lo verás cristalino.
Implementar el Apex Connector Framework
La implementación del APC que he realizado para este caso de uso, no me ha llevado más de unas pocas decenas de líneas lo que confirma que con un mínimo desarrollo podemos usar el APC.
La implementación consiste en extender 2 clases:
- Datasource.Provider que informa a Salesforce Connect de 2 puntos cruciales:
- Las capacidades de la que dotaremos la conector: ejecutar QUERYs, CREATE/DELETE/UPDATE de registros
- Como se realiza la Autenticación para acceder a la fuente
- DataSource.Connection que contiene toda la lógica necesaria y es el core de la implementación
Además deberás configurar el Remote Site Settings, y recomiendo siempre el uso de Named Credentials.
Extensión de la Clase Provider
A continuación muestro el código de la clase, es muy simple, casi todo es scaffolding copiado de la documentación de ejemplo:

Extensión de la Clase Connection
La extensión de la Database.Connection tiene diferentes partes, que si recordamos el flujo de creación de los componentes de Salesforce Connect, será muy fácil de entender.
En primer caso, informamos a Salesforce Connect cuales serán los objetos disponibles en la Interfaz, cuando el usuario haga click sobre el botón de Validate & Sync. Para ello sobrescribimos el método Sync:

Además, sobrescribimos el método Query, que devolverá los registros resultado en una estructura fijada .
Es aquí donde reside el grueso de la lógica. En mi caso he encapsulado el código en la llamada al método obtenerFilasResutado().
Este método realiza todas las invocaciones a los servicios de obtener la información de las criptomonedas y la cotización del euro.
Las funciones auxiliares getUSDToEURRate y getCriptoMarkekList tienen poco secreto:
- acceden a los Endpoints de los servicios externos mediante Callouts
- utilizan las Named Credentials definidas, (la autenticación la gestiona la clase Provider)
- parsean las respuestas obtenidas, una en JSON y la otra en XML para la información de las monedas y el tipo de cambio respectivamente



Nota: para evitar enviar demasiadas peticiones a los servicios externos, utilizo un mockeo de las respuestas durante el desarrollo.
Resultado obtenido
El resultado como era de esperar son 2 objetos, uno para la mostrar la información de las criptomonedas (External Object) y el referente a mis Valoraciones (Custom Object – que como podrás ver son de un análisis muy profundo):


La Related List en un registro concreto de criptomoneda, como en este caso Bitcoin, me permite ver la evolución de mis valoraciones y comentarios:

Mis Conclusiones
Es importante valorar las capacidades del APC, porque en ciertos escenarios su uso, puede evitarnos la construcción de interfaces complejas con sistemas con datos sensibles y grandes volúmenes, con pocas líneas APEX como hemos visto.
Si además vamos más allá, podemos preguntarnos ¿por qué limitarnos con interfaces externas? Al fin y al cabo, APC es la extensión de unas clases APEX, con lo qué ¿por qué no podemos cualquier tipo de resultado que nos interese y que no tengamos disponible en la plataforma de forma directa? Dejo que lo pienses.
Salesforce sigue trabajando y ampliando las funcionalidades de Connect y del APC, ya que por ejemplo, ahora en Spring 18 está disponible en beta, el uso de External Objects en Triggers, lo que por ejemplo, nos permite, cada vez que modifiquemos una Account, interrogar a los External Objects sobre información referente a esta Account y almacenarla en el registro (no lo he podido probar porque no tengo acceso a esa funcionalidad).
En conclusión, excepto por la barrera de acceso del licenciamiento, Salesforce Connect y el Apex Connector Framework son funcionalidades poco conocidas, nativas a la plataforma y de un gran potencialidad, que a medida que vayamos interiorizando en nuestros casos de uso, como acceso a datos generados por terceros (Big Data, AI, etc.) pueden ofrecernos capacidades hasta ahora desconocidas.
Repositorio
Todo los artefactos, están disponibles para su uso y fork en este repositorio de Bitbucket.
Enlaces de interés
En la comunidad, existen excelentes artículos de MVPs como Agustina García, Alba Rivas y Jitendra Zaa, que describen perfectamente como programar el APC, de los que recomiendo su lectura:
- Artículo de Agustina García sobre Apex Connector Framework titulado
- Artículos de Alba Rivas sobre Salesforce Connect y video de Alba muy recomendable con un conector para Google Places
- Artículo de Jitendra Zaa sobre Apex Connector Framework titulado
- API Banco Central Europeo
- API CoinMarketCap JSON API Documentation
Deja una respuesta