Objetivo

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.

Estrutura

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:

Funcionamento

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:

Definições

Mensagem

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.

Exemplos de Mensagem - contexto server-to-server

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:

Exemplos de mensagem - contexto client-to-server

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.

Interface

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.

Predicado /transactions

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

Exemplos de utilização deste predicado podem ser encontrados nos links a seguir:

Coexistência com o formato XML

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.

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.

Modelagem de transações

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, 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.

Para a documentação da transação no arquivo de definição OpenAPI, há regras para a mensagem e para os campos, conforme abaixo:

Modelagem do InternalId

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.

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
        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
        ShortCode:
          type: string
          description: Descrição breve do centro de custo
        SPED:
          type: boolean
        Class:
          type: number