La librería SDK.REST es la mejor herramienta que tenemos para hacer queries a CRM desde Javascript. Esta librería ofrece una serie de métodos con los cuales podemos interactuar con la Api REST de CRM. Uno de esos métodos es el Retrieve que incluye el parámetro Expand que vamos a analizar.
Con el método Retrieve podemos obtener un registro de CRM indicándole la entidad y el Id del mismo. Además es siempre recomendable que le indiquemos los campos que necesitamos puesto que por defecto te devolverá todos, cosa que en la mayoría de los casos no necesitaremos y además ahorraremos recursos.
La definición del método RetrieveRecord según la librería es el siguiente:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
retrieveRecord: function (id, type, select, expand, successCallback, errorCallback) { ///<summary> /// Sends an asynchronous request to retrieve a record. ///</summary> ///<param name="id" type="String"> /// A String representing the GUID value for the record to retrieve. ///</param> ///<param name="type" type="String"> /// The Schema Name of the Entity type record to retrieve. /// For an Account record, use "Account" ///</param> ///<param name="select" type="String"> /// A String representing the $select OData System Query Option to control which /// attributes will be returned. This is a comma separated list of Attribute names that are valid for retrieve. /// If null all properties for the record will be returned ///</param> ///<param name="expand" type="String"> /// A String representing the $expand OData System Query Option value to control which /// related records are also returned. This is a comma separated list of of up to 6 entity relationship names /// If null no expanded related records will be returned. ///</param> ///<param name="successCallback" type="Function"> /// The function that will be passed through and be called by a successful response. /// This function must accept the returned record as a parameter. /// </param> ///<param name="errorCallback" type="Function"> /// The function that will be passed through and be called by a failed response. /// This function must accept an Error object as a parameter. /// </param> [...] } |
El primer y el segundo parámetro son el Id y entidad del registro que queremos recuperar. Es importante notar que el nombre de la entidad es el Nombre de Esquema (Schema name) que se escribe con mayúsculas/minúsculas según está definido en la solución.
El tercer parámetro son los campos que queremos recuperar. En este caso sería una cadena de texto con los nombres (de esquema) de los campos que queremos obtener, separados por comas.
Las dos ultimas, son las funciones Callback de Exito/Error que se ejecutarán si el registro se ha devuelto bien o si se ha encontrado algún error respectivamente.
Finalmente, como cuarto parámetro tenemos el Expand. El Expand es una cadena de texto donde se incluirán los nombres de las relaciones que queremos expandir siempre en referencia al registro que estamos pidiendo. Se podrán incluir relaciones 1:N y N:1. En cada caso obtendremos un objeto distinto como resultado.
Es interesante recalcar que con los Expands no se indican qué campos de la entidad expandida quieres, sino que te devuelve todos. Es por esto que aunque en la definición de la librería diga que se pueden hasta expandir 6 relaciones, en mi opinión no es nada recomendable puesto que te devolverá en una sola llamada un volumen muy grande de datos [ 1 registro padre + (N1 registros hijos relación 1 * M1 campos cada registro) + (N2 registros hijos relación 2 * M2 campos cada registro) + … ]. Si multiplicamos esto por cada usuario de CRM que esté trabajando podemos sobrecargar el sistema.
Expand con relación 1:N
Un ejemplo sería obtener una cuenta y además todos los contactos asociados a la cuenta. Como es lógico, cuando hacemos esto obtenemos 1 resultado padre, la cuenta, y N hijos, todos los contactos relacionados con esa cuenta. La petición y deserialización sería del siguiente modo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
function RetrieveRecord () { var Id = "00000000-0000-0000-0000-000000000000"; var EntityName = "Account"; var Select = "Name, CreatedOn"; var Expand = "contact_customer_accounts"; SDK.REST.retrieveRecord( Id, EntityName, Select, Expand, RetrieveSuccessCallback, RetrieveErrorCallback ); } function RetrieveSuccessCallback (response) { console.log(response); var Name = response.Name; var CreatedOn = response.CreatedOn; //Expanded object contact_customer_accounts of type 1:N var contact_customer_accountsArray = response.contact_customer_accounts.results; for (var i = 0; i < contact_customer_accountsArray.length; i++) { //Attributes of the linked entity (contact): // var Attr1 = contact_customer_accountsArray[i].Attr1; // var Attr2 = contact_customer_accountsArray[i].Attr2; } } function RetrieveErrorCallback (error) { console.log("Error:"); console.log(error); } |
Como vemos en la siguiente imagen, el objeto response que nos devuelve como parámetro en el SuccessCallBack tiene primero los campos pedidos en el Select del registro padre (cuenta) y además, colgando del objeto contact_customer_accounts.results tenemos un Array con cada uno de los resultados hijos (contactos) y todos sus atributos.
Para recorrer el array de respuesta lo haremos como en se muestra en el código superior, con un bucle For que recorra todos los results de la expansión.
Expand con relación N:1
Ahora, en el caso opuesto, vamos a expandir una relación N:1. Esto es, queremos el padre del registro que estamos solicitando. Como no puede ser de otra manera, en este caso solo esperamos que nos devuelva un resultado y no N como en el ejemplo anterior.
Siguiendo con el ejemplo anterior, vamos a expandir la relación de “Contacto principal” de una Cuenta.
El código quedaría algo del estilo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
function RetrieveRecord () { var Id = "00000000-0000-0000-0000-000000000000"; var EntityName = "Account"; var Select = "Name, CreatedOn"; var Expand = "account_primary_contact"; SDK.REST.retrieveRecord( Id, EntityName, Select, Expand, RetrieveSuccessCallback, RetrieveErrorCallback ); } function RetrieveSuccessCallback (response) { console.log(response); var Name = response.Name; var CreatedOn = response.CreatedOn; //Expanded object account_primary_contact of type N:1 var account_primary_contactObj = response.account_primary_contact; //Attributes of the linked entity (contact): // var Attr1 = account_primary_contactObj.Attr1; // var Attr2 = account_primary_contactObj.Attr2; } function RetrieveErrorCallback (error) { console.log("Error:"); console.log(error); } |
En este caso, al disponer de un solo resultado en la expansión, se ahorra el results del objeto account_primary_contact dentro del objeto response.
Expand con relación N:N
Desconozco si es posible expandir una relación N:N pero todas las pruebas que he hecho no han funcionado. Si alguien sabe cómo hacerlo le agradecería que indicase cómo en los comentarios!
Mezclando expansiones
Como hemos indicado con anterioridad, es totalmente posible expandir varias relaciones en la misma petición (hasta 6) y por cada una de ellas obtendremos un objeto colgando del response con el nombre de la relación. Si es 1:N además éste contendrá un Array denominado results con todos los hijos del registro.
Para terminar, indicar con la extensión para Chrome HUDCRM, en la pestaña “Query constructor” podéis obtener todos estos códigos mostrados en el post de manera muy sencilla.