Documentar a estrutura, funcionamento e práticas relacionadas à mensagem padronizada TOTVS utilizando REST como padrão de comunicação e JSON como formato de mensagem.
Este documento leva em consideração que o leitor tenha um conhecimento prévio da mensagem padronizada TOTVS utilizando XML e SOAP. Caso algum termo não esteja suficientemente descrito aqui, recomenda-se consultar o documento relacionado a elaboração de mensagem padronizada em SOAP/XML, disponível aqui. |
Semelhante ao que se tem na mensagem padronizada, baseada em SOAP e XML, a estrutura é composta dos seguintes elementos:
Graficamente, a estrutura pode ser descrita conforme abaixo:
A dinâmica envolvendo o envio e recebimento de mensagens não se altera com a nova proposta. O que muda, de fato, são o formato da mensagem e a interface.
Os modos de operação continuam os mesmos: síncrono e assíncrono, sendo que neste último continuamos a ter a necessidade de uma fila e de um agente que se responsabilize por sua gestão (processador de fila).
A geração das mensagens continua a cargo dos adapters, que entregam para a Engine do EAI a estrutura de dados necessária para gerar a mensagem no padrão TOTVS. Da mesma, forma o recebimento das mensagens continua sendo intermediado pelo Engine de EAI, que determinará qual o adapter responsável por processar a mensagem recebida.
Considerando a crescente implementação de APIs nos produtos TOTVS e visando a definição de um glossário único na troca de dados entre os participantes de uma integração, estabeleceu-se a obrigatoriedade da mensagem padronizada nos seguintes contextos:
Em função do exposto acima, a definição e uso de InternalId nas transações deve seguir esta orientação:
A mensagem padronizada, utilizando JSON como formato, será composta dos elementos Header e Content.
Header: contem informações sobre a mensagem sendo trafegada, como seu identificador único, data em que foi gerada, transação ao qual se refere, entre outras. São dados equivalentes a tag MessageInformation, do formato XML. Os atributos JSON correspondentes seguem as mesmas convenções de obrigatoriedade do padrão original. As tags que não estão descritas aqui, a principio, não serão utilizadas.
Content: contem informações equivalentes a tag BusinessContent, para mensagens de negócio, ou a tag ReturnContent, para mensagens de resposta. Devido a isso, os atributos podem variar de acordo com a definição da transação. Entretanto, os atributos modelados para preencher o atributo Content, que corresponde ao contexto de uso server-to-server, devem ser os mesmos no contexto de uso client-to-server.
Quando a mensagem for de resposta, o atributo Content terá ainda os seguintes atributos:
No padrão REST/JSON, a indicação do tipo de operação - upsert ou delete - originalmente indicada na tag Event do padrão SOAP/XML, estará vinculada ao método HTTP utilizado na requisição. Mais informações serão prestadas na seção Interface deste documento. |
A tag Identification, subordinada à tag BusinessEvent, não será contemplada no formato REST/JSON. Essa tag foi sendo substituída ao longo do tempo pelos InternalIDs do corpo das mensagens. Ao migrar um adapter para utilizar o novo formato, qualquer processamento baseado na tag Identification deve ser revisto. |
Uma mensagem da transação CostCenter, na versão 2.000, no contexto de uso server-to-server, seria expressa da seguinte forma, usando o formato JSON:
{ "Header" : { "UUID" : "d6bbfa63-ca27-e2ac-0b14-101970f59a5b", "Type" : "BusinessMessage", "SubType" : "event", "Transaction" : "CostCenter", "Version" : "2.000", "SourceApplication": "P1299", "ProductName" : "PROTHEUS", "ProductVersion" : "12.1.17", "CompanyId" : "99", "BranchId" : "01", "GeneratedOn" : "2017-11-14T11:47:00-03:00", "DeliveryType" : "async", }, "Content" : { "CompanyId" : "99", "BranchId" : "01", "CompanyInternalId" : "99", "Code" : "ABC001", "InternalId" : "99|ABC001", "RegisterSituation" : "Active", "Name" : "Centro de Custo ABC001", "ShortCode" : "ABC001", "SPED" : true, "Class" : 2 } } |
A mensagem de resposta correspondente seria semelhante ao exemplo abaixo:
{ "Header" : { "UUID" : "a1b2c3d4-e5f6-g7h8-i9j0-k1l2m3n4o5p6", "Type" : "Response", "SubType" : "event", "Transaction" : "CostCenter", "Version" : "2.000", "SourceApplication" : "LGX12", "ProductName" : "LOGIX", "ProductVersion" : "12.1.15", "GeneratedOn" : "2017-11-14T11:47:15-03:00", "DeliveryType": "async" }, "Content" : { "ReceivedMessage" : { "UUID" : "d6bbfa63-ca27-e2ac-0b14-101970f59a5b", "SentBy" : "P1299", "Event" : "upsert" }, "ProcessingInformation" : { "ProcessedOn" : "2017-11-14T11:47:15-03:00", "Status" : "Ok" }, "ReturnContent" : { "ListOfInternalID" : [ { "Name" : "CostCenter", "Origin" : "99|ABC001", "Destination" : "10|1000" }, { "Name" : "Company", "Origin" : "99", "Destination" : "10" } ] } } } |
O padrão REST/JSON fornece também um modelo para lote de mensagens, onde as mensagens são agrupadas em um array JSON, de nome items.
{ "Items" : [ { "Header" : { "UUID" : "", "Type" : "", "SubType" : "", "Transaction" : "customerVendor", "Version" : "2.001", "SourceApplication": "", "ProductName" : "", "ProductVersion" : "", "GeneratedOn" : "", "DeliveryType" : "async", }, "Content" : { "Atributo1" : "", "Atributo2" : "", ... "AtributoN" : "" } },{ "Header" : { "UUID" : "", ... "Transaction" : "item", "Version" : "3.001", ... "DeliveryType" : "async" }, "Content" : { "Atributo1" : "", "Atributo2" : "", ... "AtributoN" : "" } } ] } |
O uso do formato de lote de mensagens tem algumas considerações importantes:
A transação CostCenter, versão 2.000, no contexto de uso client-to-server, seria representada em JSON conforme segue:
{ "CompanyId" : "99", "BranchId" : "01", "Code" : "ABC001", "RegisterSituation" : "Active", "Name" : "Centro de Custo ABC001", "ShortCode" : "ABC001", "SPED" : true, "Class" : 2 } |
Observe que os campos relativos a InternalId não estão presentes, por serem opcionais neste contexto de uso.
As mensagens padronizadas em formato JSON serão recebidas por um endpoint padrão, conforme descrito abaixo:
/totvseai/standardmessage/v1/{resource}
No endpoint, v1 corresponde à versão do padrão de mensagem, que pode evoluir. A versão será alterada, quando necessário, conforme o Guia de Implementação de APIs.
Em resource, pode-se informar as seguintes opções:
Salvo quando explicitamente indicado no documento, deve-se considerar que os endpoints disponibilizam os recursos previstos no Guia de Implementação de APIs para paginação, ordenação e filtro de dados. |
http://<servidor>[:<porta>]/totvseai/standardmessage/v1/transactions?batchType={batchType}?batchUUID={batchUUID} |
Onde:
Os parâmetros de paginação, ordenação e filtro de dados previstos pelo Guia de Implementação de APIs não são aplicáveis para as requisições deste predicado. |
Os métodos HTTP previstos são:
Por definição, não serão aceitas mensagens com subtipo request no método DELETE. Apenas mensagens com subtipo event serão permitidas. Quando tal situação ocorre, será retornado, no mínimo, o código HTTP 405 (Method not allowed). |
Exemplos de utilização deste predicado podem ser encontrados nos links a seguir:
No período de migração das implementações em XML para JSON, será necessário que os formatos convivam simultaneamente e sejam interoperáveis.Isso implica que a modelagem de uma transação usando o padrão REST/JSON seja compatível com a modelagem usando o padrão SOAP/XML (orientações no tópico seguinte).
Assim que todos os ERPs forem capazes de trabalhar com a nova proposta, o formato XML e os endpoints SOAP poderão ser desativados.
Para permitir a utilização dos adapters atuais, sem que seja necessário convertê-los de imediato para o formato JSON, está disponível um conversor de XML para JSON e vice-versa, implementado no formato de DLL. Para mais informações, consulte a documentação correspondente.
Para apoiar na migração de adapters do formato XML para o formato JSON, foi desenvolvido o documento Equivalência entre formatos, o qual possui orientações importantes para este processo.
O desenho de uma transação, no formato REST/JSON, deve utilizar o formato OpenAPI (anteriormente chamado Swagger), versão 3.0 em diante, em substituição ao formato XML Schema (XSD), utilizado na implementação SOAP/XML. Para mais informações sobre como implementar um documento Swagger, consulte a especificação própria do padrão.
Em nome da consistência entre os formatos, é necessário ter em mente o seguinte procedimento: ao desenvolver, por exemplo, um documento OpenAPI (padrão REST/JSON) para a transação CostCenter, versão 2.000, deve-se verificar se já existe um documento XSD da referida transação (padrão SOAP/XML). Existindo o documento, todos os atributos que definem a tag BusinessContent devem estar presentes no documento OpenAPI, para que o modelo seja considerado como sendo da transação CostCenter, versão 2.000.
Por outro lado, é possível que um documento OpenAPI seja implementado sem que haja o correspondente em XSD. Neste caso, a modelagem deve ser elaborada considerando que a transação também pode vir a ser usada no futuro, para integração server-to-server, e por isso, deve conter atributos que permitam o uso em tal contexto, mesmo que inicialmente a utilização seja no contexto client-to-server. Se isso for levado em consideração, não será necessário criar um documento XSD equivalente para a mesma transação e versão.
Para a documentação da transação no arquivo de definição OpenAPI, há regras para a mensagem e para os campos, conforme abaixo:
Conforme descrito no item Funcionamento deste documento, os atributos relativos ao InternalId devem ser modelados, independentemente do contexto de uso.
O exemplo a seguir mostra a modelagem da transação CostCenter, versão 2.000, usando o padrão OpenAPI (Swagger), considerando a obrigatoriedade da definição de InternalIds, mas não o seu uso. Ou seja, os campos de InternalId não são marcados como requeridos.
Este exemplo foi reduzido para destacar a definição do modelo de dados. Entretanto, um modelo completo deve incluir, entre outras coisas, os verbos HTTP suportados pela API e a documentação da mensagem conforme indicado anteriormente. |
{ "openapi": "3.0.0", "info": { "description": "Centro de Custo", "version": "2.000", "title": "CostCenter", "contact": { "name": "T-Talk" } }, "paths": {}, "servers": [ { "url": "http://api.totvs.com.br/" } ], "components": { "schemas": { "CostCenter": { "type": "object", "required": [ "Code", "Name", "ShortCode" ], "properties": { "CompanyId": { "type": "string", "description": "Código da empresa", "maxLength": 3 }, "BranchId": { "type": "string", "description": "Código da filial/estabelecimento/coligada" }, "CompanyInternalId": { "type": "string", "description": "InternalId da empresa" }, "Code": { "type": "string", "description": "Código do centro de custo" }, "InternalId": { "type": "string", "description": "InternalId do centro de custo" }, "RegisterSituation": { "type": "string", "description": "Indica se o centro de custo está ativo ou não.", "enum": [ "Active", "Inactive" ] }, "Name": { "type": "string", "description": "Descrição do centro de custo", "maxLength": 100 }, "ShortCode": { "type": "string", "description": "RM: Código reduzido do centro de custo" }, "SPED": { "type": "boolean", "description": "Define se o centro de custo será enviado para SPED" }, "Class": { "type": "number", "format": "int8", "description": "Classe (Analítico ou Sintético)", "enum": [ 1, 2 ] } } }, "ListOfInternalId": { "type": "object", "properties": { "ListOfInternalId": { "type": "array", "items": { "required": [ "Destination", "Name", "Origin" ], "type": "object", "properties": { "Name": { "type": "string" }, "Origin": { "type": "string" }, "Destination": { "type": "string" } } } } }, "example": "{\n \"ListOfInternalId\": [{\n \"Name\": \"InternalId\",\n \"Origin\": \"Valor1\",\n \"Destination\": \"Valor2\"\n }]\n}" } } } } |