Existe una gran demanda de integración de datos entre las diversas plataformas y sistemas disponibles en el mercado. El T6 Enterprise posibilita esta integración a través de la utilización de
WebServices o API REST, transfiriendo los datos en formato JSON de tres formas:
Obtener datos de una API/REST: consumiendo los datos de un servicio provisto por el cliente/proveedor.
Enviar datos a una API/REST: encapsular los datos almacenados en T6 Enterprise y enviarlos a un servicio provisto por el cliente/proveedor.
Disponibilizar los datos para consulta: ofrecer una estructura de datos a través de nuestra API de formularios para que algún servicio consuma los datos según la necesidad del origen.
Para visualizar el listado completo de las APIs del T6, podemos utilizar el Swagger, para información sobre la configuración y utilización, acceda a nuestra central de ayuda: Swagger.
Internamente en el T6 Enterprise las cargas de datos (ETL) se crean a través de nuestro proceso de workflow, permitiendo diversos controles, envíos de e-mails e interacción con el usuario. A continuación, un ejemplo de flujo de carga:
La herramienta que disponibilizamos para interactuar con cualquier API/REST externas al T6 es el DataloadREST. A través de él podemos disparar llamadas en diversos protocolos, métodos y autenticaciones, permitiendo consumir datos o enviar datos a WebServices disponibles en la red.
Por defecto el servicio utiliza el método POST, pero también es posible utilizar el método GET, pasando los parámetros concatenados en la URL conforme el ejemplo a continuación. Como en el caso anterior, el insert está dentro de un Stored Procedure, que concatena dinámicamente el año y el mes en la URL.
{
"Url": "https://apiqas.cliente.com.br:6244/teste-e/sysphera/integracao?ano='+@ano+'&mes='+@mes
"RequestMethod": "GET",
"AuthenticateType": "None",
"Body": ""
}
Configuración más simple, con método POST, la URL del servicio, el método de autenticación básico, usuario, contraseña y los parámetros siendo pasados en el body (paso clásico del método POST):
{
"Url": "http://sapqas.cliente.com:8001/sysphera/sysphera_dados?sap-client=300",
"RequestMethod" : "POST" ,
"AuthenticateType": "BASIC",
"UserName": "SYSPHERA",
"Password": "agrC4DkbyJuHSFwCU@",
"Body": "{
\"I_ANO\": \"2019\",
\"I_MES\": \"02\"
}"
}
Cuando el servicio no requiera autenticación, colocar None en los parámetros.
{
"Url": "https://api.cliente.com.br:6244/sysphera/listar/volume",
"AuthenticateType": "None",
"UserName": "None",
"Password": "None",
"Body": "{
\"ANO\": \"2019\",
\"MES\": \"01\"
}"
}')
En este ejemplo existe la necesidad de incluir algunas informaciones en el Header, como el Content-Type y algunos parámetros utilizando via URL Encoded.
{
"Url" : "https://api-homologacao.cliente.com.br/credenciamento/auth/oauth/v2/token" ,
"AuthenticateType" : "BASIC" ,
"UserName" : "0fd71627-a1a1-b1b1-9cd4-69c6ef34fb74" ,
"Password" : "e34af389-6054-9958-a8c4-c304244c9b81" ,
"RequestMethod" : "POST" ,
"Header": "Content-Type:application/x-www-form-urlencoded",
"Body": "scope=onboarding-sap&grant_type=client_credentials"
}'
Existen casos donde es necesario pasar el TOKEN dentro de una Cookie, que se encuentra en el Header.
{
"Url": "https://servicos.cliente.com.br/isw/api/v1/siteware/acompanhamentoFinanceiroProjeto",
"RequestMethod": "POST",
"Header": "Cookie: iPlanetDirectoryPro=\"My00YTk0LTljZDQtNjljNmVmMzRmYjc0OmUzN\";
"Body": "[{\"ano\": 2020, \"codigo\": 900001, \"despesaOrcado\": 1.50, \"despesaRealizado\":
...
}
El envío de los datos a una API utiliza la misma lógica de mensaje, la única diferencia es que en el Body estará el JSON con los datos a ser enviados.
{
"Url": "http://sapqas.cliente.com:8001/sysphera/sysphera_getdata",
"RequestMethod" : "POST" ,
"AuthenticateType": "BASIC",
"UserName": "SYSPHERA",
"Password": "agrC4DkbyJuHSFwCU@",
"Body": "[
{\"ano\": 2023, \"codigo\": 900001, \"despesaOrcado\": 1.50, \"despesaRealizado\": 1.60, \"mes
{\"ano\": 2023, \"codigo\": 900002, \"despesaOrcado\": 2.40, \"despesaRealizado\": 2.30, \"mes
{\"ano\": 2023, \"codigo\": 900003, \"despesaOrcado\": 3.20, \"despesaRealizado\": 3.50, \"mes
{\"ano\": 2023, \"codigo\": 900004, \"despesaOrcado\": 1.80, \"despesaRealizado\": 1.60, \"mes
...
]"
}
El servicio permite la utilización del protocolo oAuth. Este protocolo funciona como si fueran dos llamadas, una para la autenticación y otra para el servicio en sí, pero todo configurado en una única ejecución conforme el ejemplo a continuación.
{
"Url": "https://dev-api.cliente.com.br/sb/dados-contabeis/v1/contas?Periodo=01/01/2020",
"AuthenticateType": "oAuth",
"Header": "client_id:5ca627ad-a1a1-3680-87ac-0ededaffc59d; access_token:{{oAuthAccessToken}};
"RequestMethod": "POST",
"UserName": "",
"Password": "",
"Body":"",
"oAuthAuthEndpoint": "https://api.cliente.com.br/oauth/grant-code",
"oAuthAuthRequestMethod": "POST",
"oAuthAuthRequestHeader": "Content-Type:application/json",
"oAuthAuthRequestBody": "{\"client_id\": \"5ca627ad-608a-3680-87ac-0ededaffc59d\", \"redirect_
"oAuthAuthRequestAuthenticateType": "",
"oAuthAuthRequestUserName": "",
"oAuthAuthRequestPassword": "",
"oAuthTokenEndpoint": "https://api.cliente.com.br/oauth/access-token",
"oAuthTokenRequestMethod": "POST",
"oAuthTokenRequestHeader": "Content-Type:application/x-www-form-urlencoded",
"oAuthTokenRequestBody": "grant_type=authorization_code&code={{oAuthGrantCode}}",
"oAuthTokenRequestAuthenticateType": "Basic",
"oAuthTokenRequestUserName": "5ca627ad-608a-3680-87ac-0ededaffc59d",
"oAuthTokenRequestPassword": "87d147d1-a607-3d0f-9de2-78d9a11c0fe8"
}')
El T6 Enterprise posee una segunda forma de disponibilizar los datos para consumo del cliente, a través de una API REST incorporada en cada formulario de datos del tipo VENTANA. Son dos llamadas de APIs autenticadas a través de un token. La primera API retorna los metadatos de la consulta, con la cantidad de líneas y el descriptivo de las columnas, mientras que la segunda API retorna el dataset con los datos del formulario. La llamada de la primera no es obligatoria y la segunda API (offset) permite la paginación cuando tenemos un gran volumen de datos.
Para que podamos utilizar las APIs, algún usuario administrador multi-aplicaciones necesita crear un token de acceso. Esto debe hacerse en la creación del usuario, en la pestaña de Services conforme se presenta en la figura a continuación.
El token es un conjunto de caracteres que puede tener una validez y permitirá el acceso a las APIs de los formularios. Hará la autenticación en lugar de un usuario y contraseña. Este token puede tener un plazo de validez y podrá ser revocado/eliminado en cualquier momento.
Los gestores de la aplicación definirán cuál (o cuáles) formulario será utilizado para acceder a los datos via API. Cualquier formulario del tipo ventana podrá ser creado, independientemente si fue creado a través de una tabla de datos o a través de consulta.
La información importante para usar en la API es el código del formulario conforme se presenta a continuación:
Antes del Service Principal, no había una manera práctica de que un servicio externo o proceso en segundo plano se conectara al T6 via API sin un usuario logueado.
El Service Principal resuelve esto proporcionando un mecanismo basado en token que permite que servicios y aplicaciones externas se autentiquen en el T6 y consuman sus APIs sin requerir credenciales de usuario o una sesión activa.
Los casos de uso típicos incluyen:
- Cargas de datos automatizadas de sistemas externos via API REST del T6.
- Aplicaciones personalizadas que consumen datos de formularios de datos u objetos del Explorer del T6.
- Integraciones servidor a servidor ejecutadas por programación o bajo demanda, sin interacción del usuario.
Todas las solicitudes a la API de Servicio utilizan la siguiente estructura:
Endpoint: POST http://su-dominio/api/Services/Execute
Headers necesarios:
| Header | Valor |
|---|---|
Content-Type |
application/json |
Campos del Request Body:
| Campo | Obligatorio | Descripción |
|---|---|---|
Url |
Sí | El endpoint interno del T6 a ser llamado |
Token |
Sí | El token de servicio generado en la pestaña Servicios |
Data |
No | Payload para la solicitud interna |
Determinando GET vs POST internamente:
La presencia del campo Data determina cómo el T6 trata la solicitud interna:
Data → la llamada interna es tratada como GET:{
"Url": "Menu/GetItems",
"Token": "su-token-de-servicio"
}
Data → la llamada interna es tratada como POST:{
"Url": "Resource/GetWords",
"Token": "su-token-de-servicio",
"Data": ["Options", "Help", "Logout"]
}
La llamada externa a
api/Services/Executees siempre POST, independientemente del método interno utilizado.
El comportamiento de un token de servicio depende de su configuración:
Si necesita rotar o renovar un token, elimine el servicio existente y cree uno nuevo — un nuevo token será generado automáticamente en la creación.
Esta es la primera API que llamaremos. En ella, tendremos el listado con los nombres de las columnas a las que accederemos y la cantidad de líneas existente en el Dataset.
Para esta llamada, no necesitaremos el parámetro data, usaremos solo la URL y el Token.
La URL será Worksheet/CreateOrGet?type=dataform&typeCode=1996, siendo el typeCode (en este ejemplo el 1996) el código del formulario de datos a ser consumido.
{
"Url":"Worksheet/CreateOrGet?type=dataform&typeCode=1996",
"Token":"1fae0b70e3d24d88b67208301b1c1eb1"
}
A continuación la llamada de la API y el retorno, presentando que el formulario posee 51 líneas y el encabezado de las columnas.
Por defecto el Content-Type vendrá con el tipo Text/Plain, como en el Body tenemos un JSON, necesitamos cambiar el Content-Type a Application/JSON, de lo contrario, se generará el siguiente error: 415 - Unsupported Media Type.
La API Offset se utiliza efectivamente para consumir los datos. Dependiendo del volumen de datos, puede ser paginada, pues además del código del formulario de datos (typeCode), también tenemos como atributo la línea inicial (start) y la cantidad de líneas (length) que buscaremos.
El parámetro length tiene un límite máximo de 2000 líneas por llamada, en caso de que el número de líneas supere este valor, será necesario realizar múltiples llamadas paginadas. Si se intenta informar un valor mayor que 2000, la API retornará el error 400 - Bad Request.
La URL será Worksheet/Offset?code=&type=dataform&typecode=1996&start=0&length=20&metadata=false. En este ejemplo estoy iniciando desde la línea inicial "0" y traeré solo 20 líneas del total de 51.
En esta llamada el parámetro Data del Body es necesario y será fijo, siempre pasando de la siguiente forma:
"Data":{"Comparator":0,"Operator":0,"Filters":[]}
{
"Url":"Worksheet/Offset?code=&type=dataform&typecode=1996&start=0&length=20&metadata=false
"Token":"1fae0b70e3d24d88b67208301b1c1eb1",
"Data":{"Comparator":0,"Operator":0,"Filters":[]}
}
A continuación la llamada de la API retornando los datos. El retorno siempre estará en el mismo formato de lista encadenada con LÍNEAS y COLUMNAS.
Note que iniciamos con la línea RowIndex=0 y luego todas sus columnas ColumnIndex=0, 1, 2... El valor es lo que está en el campo VALUE. Es decir, la celda {0,5} tiene el valor "10"
En este ejemplo anterior, verificando en el formulario lo que tenemos en ROW=0 y COLUMN=5, tenemos el valor 10.
También podemos realizar la llamada de la API via CURL, utilizando el CMD. Para ello, vamos a ejecutar el CMD como administrador y a continuación ejecutar la siguiente llamada CURL:
echo. && curl --location "http://su-dominio/api/Services/Execute" --header "Content-Type: application/json" --data "{\"Url\":\"Worksheet/Offset?code=^&type=dataform^&typecode=6935^&start=0^&length=255^&metadata=false\",\"Token\":\"3ef450hp121247c68fc9faaabbb123\",\"Data\":{\"Comparator\":0,\"Operator\":0,\"Filters\":[]}}"
Al ejecutar este CURL, tendremos la visualización de los datos del objeto informado conforme el ejemplo a continuación:
Para localizar los valores de los parámetros de una API, utilizaremos una herramienta para captura de tráfico de red durante la ejecución del T6Enterprise, para poder visualizar los valores que están siendo utilizados durante la ejecución de las acciones en el sistema. En este ejemplo utilizaremos la API Offset y demostraremos cómo localizar los parámetros necesarios para aplicar filtros a través del campo Data en el request body de la propia API.
Para aplicar filtros en la API Offset, necesitaremos utilizar una herramienta que realice la captura del tráfico de red (en nuestro ejemplo, utilizaremos el Fiddler Classic).
/api/Worksheet/Offset... con un doble clic.{
"Url":"Worksheet/Offset?code=&type=dataform&typecode=3232&start=0&length=20&metadata=false
"Token":"1fae0b70e3d24d88b67268302b1d1eb1",
"Data":{"Comparator":0,"Operator":0,"Filters":[{"Comparator":0,"Operator":0,"Filters":[],"Code":"413|codUser","Value":"admin"},{"Comparator":0,"Operator":0,"Filters":[{"Comparator":0,"Operator":0,"Filters":[],"Type":"column","Code":"1026","Value":"Brindes"}],"Type":"column","Code":"1026"}]}
}
De esta forma, al ejecutar la API, tendremos el retorno solo de los datos conforme los filtros aplicados.
Para que un usuario pueda acceder al sistema sin utilizar las credenciales, necesitaremos un Token de acceso para él, con el cual generaremos una URL para el acceso. Para ello utilizaremos la API Integration.
Para tener acceso al Token de un usuario, necesitaremos realizar una consulta en nuestra base de datos, utilizaremos el siguiente comando SQL:
select dbo.UrlEncode(dbo.VarBinaryToBase64(dbo.Encrypt('bmeredyk?~/l/cms/home'))) as token
Al utilizar este comando, la base de datos nos retornará el Token que utilizaremos para generar la URL que concederá el acceso al usuario. En el ejemplo anterior, tenemos la ruta 'bmeredyk?/l/cms/home', en la cual bmeredyk es el usuario para el que generaremos el token de acceso y /l/cms/home es el endpoint de la página que se abrirá cuando el usuario haga clic en la URL, en este caso, la página Home de nuestra aplicación. Podemos modificar el endpoint haciendo que el usuario acceda al sistema en una página específica.
Para generar la URL de acceso, utilizaremos un script de Powershell, para ello, necesitaremos instalar el módulo Invoke-SQLcmd de SQLServer (Invoke-SQLcmd) en nuestro Powershell. Utilizaremos el siguiente script:
$tokenDS = Invoke-Sqlcmd -Query "select dbo.UrlEncode(dbo.VarBinaryToBase64(dbo.Encrypt('bmeredyk?~/l/explorer/2437'))) as token;" -As DataSet -ConnectionString "Server=TESTE;Database=EXEMPLO;TrustServerCertificate=true;user id=****;password=****"
$token = $tokenDS.Tables[0].token
$Url = $('http://TESTE:9900/api/Authentication/Integration?token=' + $token + '')
Write-Host "URL gerada: $Url"
Invoke-WebRequest -URI $Url -UseBasicParsing -Headers @{'content-type' = 'application/json'} -Method 'GET'
Para utilizar este script, el usuario debe tener acceso a la base de datos y utilizar sus credenciales de inicio de sesión en la connectionstring.
Al ejecutar este script, se generará una URL de acceso conforme el ejemplo a continuación:
El T6 Enterprise soporta tres formas de integración de datos via API REST/WebServices:
El DataloadREST es la herramienta del T6 utilizada para interactuar con APIs/REST externas. A través de él es posible disparar llamadas en diversos protocolos y métodos. Los métodos de autenticación soportados son:
El protocolo oAuth en el DataloadREST funciona como dos llamadas encadenadas configuradas en una única ejecución:
oAuthAuthEndpoint) para obtener el código de autorización.oAuthTokenEndpoint).access_token generado (disponible via {{oAuthAccessToken}}), el T6 ejecuta la llamada al servicio final informado en Url.El Service Principal es un mecanismo basado en token que permite que servicios y aplicaciones externas se autentiquen en el T6 y consuman sus APIs sin requerir credenciales de usuario o una sesión activa.
Antes del Service Principal, no había una manera práctica de que un servicio externo o proceso en segundo plano se conectara al T6 via API sin un usuario logueado. Los casos de uso típicos incluyen cargas de datos automatizadas, aplicaciones personalizadas e integraciones servidor a servidor por programación.
El parámetro length de la API Offset tiene un límite máximo de 2000 líneas por llamada. En caso de que el volumen de datos sea superior a ese valor, será necesario realizar múltiples llamadas paginadas utilizando los parámetros start y length.
Si se informa un valor mayor que 2000, la API retornará el error 400 - Bad Request.
Worksheet/CreateOrGet): retorna los metadatos del formulario de datos, incluyendo los nombres de las columnas y la cantidad total de líneas en el dataset. No requiere el parámetro Data en el body.Worksheet/Offset): retorna efectivamente los datos del formulario, con soporte a paginación via start y length. Requiere el parámetro Data en el body con el formato {"Comparator":0,"Operator":0,"Filters":[]}.La llamada a la API CreateOrGet no es obligatoria, pero es útil para conocer la estructura y el volumen de los datos antes de paginarlos.
Este error ocurre cuando el Content-Type de la solicitud no está configurado correctamente. Por defecto, algunas herramientas envían el Content-Type como Text/Plain, pero como el body de la solicitud contiene un JSON, es obligatorio definir el Content-Type como Application/JSON.
Para aplicar filtros en la API Offset, es necesario capturar los parámetros correctos usando una herramienta de captura de tráfico de red, como el Fiddler Classic. El proceso es:
/api/Worksheet/Offset..., acceda a la pestaña Inspectors > Raw y copie el contenido de la última línea.El comportamiento del token depende de la configuración realizada en la pestaña Servicios del usuario administrador:
Para rotar un token, elimine el servicio existente y cree uno nuevo — un token será generado automáticamente.
Utilice la API Integration del T6. El proceso involucra dos etapas:
dbo.UrlEncode(dbo.VarBinaryToBase64(dbo.Encrypt('usuario?~/endpoint'))) sustituyendo usuario por el login del usuario y /endpoint por la ruta de la página de destino.http://su-dominio/api/Authentication/Integration?token=<token> y compártala con el usuario.Esta URL puede ser generada via PowerShell con el módulo Invoke-Sqlcmd, conforme se documenta en la sección 4.2.