Índice |
---|
Documentar a estrutura, funcionamento e práticas relacionadas a à mensagem padronizada TOTVS utilizando REST como padrão de comunicação e JSON como formato de mensagem.
Informações | ||
---|---|---|
| ||
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 Padrão para criação relacionado a elaboração de mensagem padronizada em SOAP/XML, disponível no portal de Integrações TOTVS aqui. |
A partir da estrutura original da Semelhante ao que se tem na mensagem padronizada, baseada em SOAP e XML, temos os a estrutura é composta dos seguintes elementos:
Graficamente, a nova proposta 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.
...
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.
A mensagem padronizada, utilizando JSON como formato, será composta dos seguintes elementos:
header: contem informações 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. Quando a mensagem for de resposta, o atributo content terá a seguinte estrutura:
Informações | ||
---|---|---|
| ||
Nesta nova proposta, a indicação do tipo de operação - upsert ou delete - está vinculada ao método HTTP utilizado na requisição. Mais informações serão prestadas na seção Interface deste documento. |
Uma mensagem da transação CostCenter, versão 2.000, seria expressa da seguinte forma, usando o formato JSON proposto:
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:
Aviso | ||
---|---|---|
| ||
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:
Bloco de código | ||
---|---|---|
| ||
{
"Header | ||
Bloco de código | ||
| ||
{ "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" : { "CompanyIdUUID" : "99d6bbfa63-ca27-e2ac-0b14-101970f59a5b", "BranchIdType" : "01BusinessMessage", "CompanyInternalId "SubType" : "99event", "Code "Event" : "ABC001upsert", "InternalId "Transaction" : "99|ABC001CostCenter", "RegisterSituation "Version" : "Active2.000", "NameSourceApplication" : "P1299"Centro, de Custo ABC001", "ShortCode "ProductName" : "ABC001PROTHEUS", "SPED "ProductVersion" : true, "Class" : 2"12.1.17", } } |
A mensagem de resposta correspondente seria semelhante ao exemplo abaixo:
Bloco de código | ||
---|---|---|
| ||
{ "headerCompanyId" : {"99", "UUIDBranchId" : "a1b2c3d4-e5f6-g7h8-i9j0-k1l2m3n4o5p601", "typeGeneratedOn" : "Response2017-11-14T11:47:00-03:00", "subTypeDeliveryType" : "eventasync", }, "transactionContent" : "CostCenter",{ "versionCompanyId" : "2.00099", "sourceApplicationBranchId" : "LGX1201", "productName "CompanyInternalId" : "LOGIX99", "Code" "productVersion: "ABC001", "InternalId" : "12.1.1599|ABC001", "generatedOn "RegisterSituation" : "2017-11-14T11:47:15-03:00Active", "deliveryTypeName" : "async" Centro de Custo }ABC001", "content "ShortCode" : { "ABC001", "SPED" : true, "Class" : 2 } } |
A mensagem de resposta correspondente seria semelhante ao exemplo abaixo:
Bloco de código | ||
---|---|---|
| ||
{ "Header"receivedMessage" : { "UUID" : "d6bbfa63a1b2c3d4-ca27e5f6-e2acg7h8-0b14i9j0-101970f59a5bk1l2m3n4o5p6", "sentByType" : "P1299Response", "SubType" : "event", "eventTransaction" : "upsertCostCenter", "Version" : "2.000", }"SourceApplication" : "LGX12", "processingInformationProductName" : { "LOGIX", "ProductVersion" : "12.1.15", "processedOnGeneratedOn" : "2017-11-14T11:47:15-03:00", "statusDeliveryType" : "ERRORasync", }, "detailsContent" : [{ "ReceivedMessage" : { { "UUID" : "d6bbfa63-ca27-e2ac-0b14-101970f59a5b", "codeSentBy" : "FE001P1299", "messageEvent" : "upsert"Mensagem padrão no formato incorreto.", }, "detailedMessageProcessingInformation" : ""{ "ProcessedOn" }: "2017-11-14T11:47:15-03:00", "Status" : "Ok" { }, "codeReturnContent" : "AE004", { "messageListOfInternalID" : "Empresa[ não configurada para integração.", { "detailedMessage" : "" "Name" : "CostCenter", } ] "Origin" }: "99|ABC001", "returnContent" : { "Destination" : "10|1000" "listOfInternalID" : [}, { "nameName" : "CostCenterCompany", "originOrigin" : "99|ABC001", "destinationDestination" : "10|1000" }, {] } "name" : "Company", "origin" : "99", } } |
Para mensagem de Resposta Assíncronas o método do envio deve ser POST, pois esta sendo trafegada a resposta, independente da operação original. Para obter o processo da mensagem original pode se acessar a propriedade Content.ReceivedMessage.Event.
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.
Bloco de código | ||
---|---|---|
| ||
{ "Items" : [ { "destination" : "10" "Header" : { } "UUID" : ]"", } } } |
A nova proposta fornece também um modelo para lote de mensagens, que corresponde a um array JSON, onde cada elemento corresponde a uma mensagem no formato JSON.
Bloco de código | ||
---|---|---|
| ||
{ "itemsType" : ["", { "headerSubType" : {"", "UUIDEvent" : "", "typeTransaction" : "customerVendor", "subTypeVersion" : "2.001", "transactionSourceApplication" : "customerVendor", "versionProductName" : "2.001", "sourceApplicationProductVersion" : "", "productNameGeneratedOn" : "", "productVersionDeliveryType" : "async", }, "generatedOnContent" : "",{ "deliveryTypeAtributo1" : "async", }, "Atributo2" : "", "content" : { ... "atributo1AtributoN" : "", } "atributo2" : ""},{ "Header" : ...{ "atributoNUUID" : "", } ... },{ "headerTransaction" : {"item", "UUIDVersion" : "3.001", ... "transactionDeliveryType" : "itemasync", "version" : "3.001"}, "Content" : ...{ "deliveryTypeAtributo1" : "async" , }, "content"Atributo2" : {"", "atributo1" : "",... "atributo2AtributoN" : "", ...} } "atributoN" : "" } } ] }] } |
O uso do formato de O lote de mensagens tem algumas características considerações importantes:
As mensagens padronizadas em formato JSON serão recebidas por um endpoint padrão, conforme descrito abaixo:
/totvseai/standardmessage/v1
Neste endpoint estarão disponíveis dois predicados ou entidades:
Informaçõ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. |
URL completa: /totvseai/standardmessage/v1/transactions?batchType={batchType}.
Nota |
---|
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 para o endpoint são:
Exemplos de utilização deste endpoint podem ser encontrados nesta página .
URL completa: /totvseai/standardmessage/v1/contents/{transactionID_version}/{internalID}.
Os métodos previstos são:
...
Informações | ||
---|---|---|
| ||
O formato de mensagem utilizado nas requisições para o endpoint /contents é mais simples, já que não requer as informações de cabeçalho para realizar o controle da mensagem. A proposta do modelo é apenas utilizar-se do modelo de mensagem padronizada para trafegar informações entre as partes. Na prática, o modelo de dados que será trafegado nas requisições corresponde ao atributo content do modelo completo, usado pelo endpoint /transactions. |
Exemplos de utilização deste endpoint podem ser vistos aqui.
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. Assim que todos os ERPs forem capazes de trabalhar com a nova proposta, o formato XML e os endpoints SOAP poderão ser desativados.
...
A transação CostCenter, versão 2.000, no contexto de uso client-to-server, seria representada em JSON conforme segue:
Bloco de código | ||||
---|---|---|---|---|
| ||||
{
"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:
Informaçõ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. |
Painel | ||
---|---|---|
| ||
http://<servidor>[:<porta>]/totvseai/standardmessage/v1/transactions?batchType={batchType}?batchUUID={batchUUID} |
Onde:
Nota |
---|
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:
Informações | ||
---|---|---|
| ||
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). |
Informações | ||
---|---|---|
| ||
Diante do descrito até o momento, há duas formas de se indicar a operação de uma mensagem do tipo BusinessMessage: via métodos HTTP (POST e DELETE) e via atributo Event. Sempre que for possível determinar a operação pelos atributos do canal, esta será a informação prevalente, como é o caso do canal REST, onde os métodos HTTP provêm essa indicação. Neste caso, pode ocorrer sobre posição da informação no atributo Event da mensagem, se ele não for compatível com a indicação do canal. O atributo Event, dentro da mensagem, será considerado apenas nos casos onde o canal não fornecer a indicação da operação, como é o caso do canal AMQP. |
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 Json Schema, Draft 4 ou superior, em substituição ao formato XML Schema (XSD) utilizado na implementação SOAP/XML. Para mais informações sobre como implementar um documento no formato Json Schema 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 Json Schema (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 tipo equivalente no documento Json Schema, para que o modelo seja considerado como sendo da transação CostCenter, versão 2.000.
Por outro lado, é possível que um documento Json Schema 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 Json Schema, 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 Branch, versão 2.001, usando o padrão Json Schema, 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.
Informações |
---|
Este exemplo foi reduzido para destacar a definição do modelo de dados. Entretanto, um modelo completo deve incluir, entre outras coisas, a documentação da mensagem conforme indicado anteriormente. |
Bloco de código | ||
---|---|---|
| ||
{
"$schema": "https://raw.githubusercontent.com/totvs/ttalk-standard-message/master/jsonschema/schemas/events/branch_2_001.json#",
"info": {
"description": "Contrato de Mensagem Padronizada para a entidade filial (Branch) para produtos TOTVS",
"version": "2.001",
"title": "Branch",
"contact": {
"name": "T-Talk",
"url": "API.Totvs.com.br",
"email": "[email protected]"
},
"x-totvs": {
"transactionMessageDocumentation": {
"subType": "event",
"businessContentType": {
"type": "object",
"$ref": "#/definitions/BranchType"
},
"returnContentType": {
"type": "object",
"$ref": "https://raw.githubusercontent.com/totvs/ttalk-standard-message/master/jsonschema/schemas/ListOfInternalId_1_000.json#/definitions/ReturnContentWithModelType"
}
},
"messageDocumentation": {
"name": "Branch",
"description": "Filial",
"segment": "FrameWork"
},
"productInformation": [
{
"product" : "protheus",
"contact": "[email protected]",
"description": "Cadastro de Filial",
"adapter": "apcfg230i.prw",
"helpUrl": "link aqui"
}
]
}
},
"definitions": {
"BranchType": {
"type": "object",
"properties": {
"CompanyCode": {
"type": "string",
"example": "D",
"description": "Código da Empresa",
"x-totvs": [
{
"product": "protheus",
"Field": "XX8.XX8_CODIGO",
"Required": false,
"Type": "Char",
"length": "12",
"avialable": true,
"canUpdate": false
}
]
},
"internalId": {
"description": "InternalId da entidade",
"type": "string",
"example": "01",
"x-totvs": [
{
"product": "protheus",
"Field": "XX8.XX8_CODIGO",
"Required": false,
"Type": "Char",
"length": "100",
"avialable": true,
"canUpdate": false
}
]
},
"Description": {
"type": "string",
"example": "Filial São Paulo 1",
"description": "Descrição",
"x-totvs": [
{
"product": "protheus",
"Field": "XX8.XX8_NOME",
"Required": false,
"Type": "Char",
"length": "100",
"avialable": true,
"canUpdate": false
}
]
},
"Code": {
"type": "string",
"example": "D SP 01",
"description": "Filial/Codigo Unidade"
},
(...)
},
"required":["CompanyCode"]
}
}
}
|
...