Child pages
  • Implementação de APIs com Mensagem Padronizada
Skip to end of metadata
Go to start of metadata

Nova documentação disponível

O documento abaixo está sendo mantido apenas para fins de histórico. Para obter instruções mais atuais sobre desenvolvimento de APIs, consulte o Guia de Implementação de Integrações.


Este artigo visa orientar sobre o desenho e implementação de APIs TOTVS respeitando as orientações do guia de implementação de APIs, bem como o modelo de conteúdo definido nas transações de mensagem padronizada TOTVS.

Orientações gerais

  1. Definição da Mensagem Padronizada no modelo Json/JsonSchema.

    1. Verifique se a entidade sobre a qual a API atuará possui uma transação já definida no repositório de mensagens padronizadas TOTVS.

      No portal api.totvs.com.br, consulte o item Mensagem Padronizada, subitem Lista de Serviços.

      No TFS, acesse a Project Collection TOTVSMSGXML (http://tfs2015.totvs.com.br:8080/tfs/TOTVSMSGXML).

      1. Consulte o repositório de mensagens padronizadas em formato JSON. Primeiramente, a pasta STABLE/messages-json/jsonschema, depois a pasta DEV/messages-json/jsonschema.

      2. Se não encontrar uma transação, consulte o repositório de mensagens em formato XML, verificando as pastas STABLE/messages-xml/xmlschema e DEV/messages-xml/xmlschema.

      3. Selecione, sempre que possível, a maior versão da transação.

    2. Existindo apenas no repositório XML uma transação compatível, deve-se criar o documento Json Schema equivalente ao documento XSD.

      1. O documento Json Schema deve ser armazenado no TFS, na pasta DEV/messages-json/jsonschema.

      2. O modelo de dados pode ser segmentado em blocos menores, desde que obedeçam a estrutura hierárquica e a estrutura e campos seja equivalente ao documento XSD. Caso a hierarquia seja alterada ou seja retirado ou adicionado campos no modelo, isso implica em uma nova versão da transação. Exemplos de segmentação serão mostrados adiante neste documento.

    3. Havendo necessidade de se criar uma nova versão da transação, esta pode ser criada apenas no repositório JSON, desde que se siga as orientações previstas na documentação de elaboração de mensagem padronizada SOAP/XML, realizando os devidos ajustes para o formato JSON.

      1. Lembrando que as versões devem começar de 2.000 pois, por convenção, foi a partir desta que se iniciou o uso de InternalId.

      2. Sempre que possível, utilizar padrões internacionais, conforme passo 3 do processo de elaboração de API e mensagens padronizadas.

        Para saber se já existe uma mensagem de conta contábil, por exemplo, pesquise no Google usando "account xsd oasis repository".

      3. Transações criadas para atender uma exigência legal devem se ater estritamente ao que é definido pela legislação. Nestes casos, o nome da transação e dos campos podem ser em português, se a legislação exigir.

  2. Definição da API e seus Endpoints

    1. Modele o documento da API usando o padrão OpenAPI 3.0, seguindo as orientações para o Guia de APIs.
      1. As tags x-totvs devem ser usadas para documentar a mensagem e os atributos do modelo de dados. Quando houver atualização do modelo de dados para uma API, deve-se registrar na tag x-totvs a versão de produto a partir da qual aquele modelo está em vigor na API.
      2. Os modelos de dados em Mensagem Padronizada devem referenciar os respectivos tipos definidos nos documentos Json Schema no Github da TOTVS.
      3. Em relação ao internalId e ListOfInternalId (retorno), seguir as orientações do item modelagem de transações.
      4. O uso de OData é opcional, sendo indicado para os casos onde a filtragem de registros necessite de mais recursos.
      5. Em relação ao versionamento, veja o item correspondente, neste documento.
      6. O nome da transação deve estar no plural, para manter consistência com o guia de implementação de APIs (ver item Estrutura de URLs).
        Modelo: http://{servidor}:{porta}/api/{agrupador}/{versao_transacao}/{nome_transacao}.
        Exemplo: http://api.totvs.com.br:8080/api/financeiro/v2.5/accountantAccounts.
    2. Submeta o documento OpenAPI para análise e aprovação.
      1. Pelos POs de segmento, conforme passo 5 do processo de elaboração de API e mensagens padronizadas.
      2. Criar um tópico no Ryver (forum API) com o nome da mensagem a ser aprovada.
      3. Pelo comitê de integração, conforme orientações do passo 6 do processo.
    3. Após aprovação da mensagem pelo comitê, o responsável pela modelagem deve mover o documento, no TFS, para a pasta STABLE/messages-json/jsonschema, bem como publicar a API no portal api.totvs.com.br.

Documentação nos Verbos da API


Ao declarar uma API, é obrigatório inserir para cada verbo a documentação interna, e esta deve conter as seguintes informações:

Exemplo
(...),
"paths": {
        "/Branch": {
            "get": {
                "tags": [
                    "Branch"
                ],
                "summary": "Retorna todas as Filiais da base",
                "x-totvs": {
                    "productInformation": [
                        {
							"product": "protheus",
                            "available": true,
                            "note": "Este verbo esta disponivel com todos os parametros",
                            "minimalVersion": "12.1.21"
                        }
                    [
                },
                "description": "Retorna todas as Filiais da base",
                "operationId": "getBranch",
                "parameters": [{
                        "$ref": "https://raw.githubusercontent.com/totvs/ttalk-standard-message/master/jsonschema/apis/types/totvsApiTypesBase.json#/parameters/Authorization"
                    }, {
                        "$ref": "https://raw.githubusercontent.com/totvs/ttalk-standard-message/master/jsonschema/apis/types/totvsApiTypesBase.json#/parameters/Order"
                    }, {
                        "$ref": "https://raw.githubusercontent.com/totvs/ttalk-standard-message/master/jsonschema/apis/types/totvsApiTypesBase.json#/parameters/Page"
                    }, {
                        "$ref": "https://raw.githubusercontent.com/totvs/ttalk-standard-message/master/jsonschema/apis/types/totvsApiTypesBase.json#/parameters/PageSize"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Operação realizada com sucesso",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "https://raw.githubusercontent.com/totvs/ttalk-standard-message/master/jsonschema/schemas/Branch_2_001.json#/definitions/PagedBranchs"
                                }
                            }
                        }
                    }
                }
            },
			(...),
	},
	(...),
}



A propriedade x-totvs indica as informações de documentação interna. Ela contem array de objetos, onde cada item deve ser referente a um produto.  

Cada Item deve conter as seguintes informações:

  • product: nome do produto ao qual se refere aquela informação. ex: protheus.
  • avaliable: campo booleano que indicia de o verbo esta implementado no produto.
  • note: observações sobre o verbo referente ao produto, como regras especificas.
  • minimalVersion: a versão minima na qual o verbo foi implementado no produto.

Segmentação do modelo de dados

Partindo de um modelo XML como base, veremos a seguir um exemplo de uma possível implementação de API usando segmentação do modelo de dados.

O modelo de dados em Json Schema será compartilhado no Github da TOTVS e deve ser referenciado na documentação da API pela sua URL, conforme apresentado no exemplo da sessão anterior.

Para este exemplo será utilizado o modelo XML Contract_2_000.xsd, representado graficamente a seguir (clique na imagem para expandir).

Convertendo este modelo "como ele é" para o formato Json Schema, teríamos o seguinte documento (alguns elementos previstos para documentação da mensagem padronizada foram omitidos para melhor compreensão):

Contract 2.000 - OpenAPI - monolítico
{   
    "$schema": "https://raw.githubusercontent.com/totvs/ttalk-standard-message/master/jsonschema/schemas/events/contract_2_000.json#",
    
  (...),
  "definitions": {
      "Contract": {
        "type": "object",
        "properties": {
          "CompanyId": {
            "type": "string"
          },
          "BranchId": {
            "type": "string"
          },
          "CompanyInternalId": {
            "type": "string"
          },
          "InternalId": {
            "type": "string"
          },
          "ContractNumber": {
            "type": "string"
          },
          "ContractReview": {
            "type": "string"
          },
          "ProjectInternalId": {
            "type": "string"
          },
          "BeginDate": {
            "type": "string",
            "format": "date-time"
          },
          "FinalDate": {
            "type": "string",
            "format": "date-time"
          },
          "CustomerCode": {
            "type": "string"
          },
          "CustomerInternalId": {
            "type": "string"
          },
          "ContractTotalValue": {
            "type": "number",
            "format": "float"
          },
          "ContractTypeCode": {
            "type": "string"
          },
          "ContractTypeInternalId": {
            "type": "string"
          },
          "ListOfSheet": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "SheetNumber": {
                  "type": "string"
                },
                "SheetTypePoperty": {
                  "type": "string"
                },
                "UnitPrice": {
                  "type": "number",
                  "format": "float"
                },
                "SheetTotalValue": {
                  "type": "number",
                  "format": "float"
                },
                "ListOfItem": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "ItemCode": {
                        "type": "string"
                      },
                      "ItemInternalId": {
                        "type": "string"
                      },
                      "AccountantAcountCode": {
                        "type": "string"
                      },
                      "AccountantAcountInternalId": {
                        "type": "string"
                      },
                      "CostCenterCode": {
                        "type": "string"
                      },
                      "CostCenterInternalId": {
                        "type": "string"
                      },
                      "AccountingItemCode": {
                        "type": "string"
                      },
                      "AccountingItemInternalId": {
                        "type": "string"
                      },
                      "ClassValueCode": {
                        "type": "string"
                      },
                      "ClassValueInternalId": {
                        "type": "string"
                      },
                      "ItemQuantity": {
                        "type": "number",
                        "format": "float"
                      },
                      "ItemUnitPrice": {
                        "type": "number",
                        "format": "float"
                      },
                      "ItemTotalValue": {
                        "type": "number",
                        "format": "float"
                      },
                      "PercentageOfDiscount": {
                        "type": "number",
                        "format": "float"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "description": "Contrato"      
    }
  }
}

Entretanto, utilizar o modelo desta forma tem vários problemas como, por exemplo, na modificação do contrato, onde teríamos que enviar também as páginas (Sheet) do contrato e os itens das páginas.

Por isso, a segmentação do modelo de dados é permitida, desde que mantenha a estrutura e atributos do modelo XML original.

Nosso modelo Json Schema poderia ser segmentado em 3 submodelos:

  • ContractModel, correspondente ao cabeçalho do contrato.
  • SheetModel, correspondente às folhas do contrato.
  • ItemModel, correspondente aos itens vinculados às folhas do contrato.

Convertendo isso para o modelo Json Schema, teríamos o seguinte, lembrando que elementos como as tags de documentação foram omitidos por questões didáticas.

Contract 2.000 - OpenAPI - segmentado
{
	"$schema": "https://raw.githubusercontent.com/totvs/ttalk-standard-message/master/jsonschema/schemas/events/contract_2_000.json#",

	(...),
	"definitions": {
		"ContractModel": {
			"type": "object",
			"properties": {
				"CompanyId": {
					"type": "string"
				},
				"BranchId": {
					"type": "string"
				},
				"CompanyInternalId": {
					"type": "string"
				},
				"InternalId": {
					"type": "string"
				},
				"ContractNumber": {
					"type": "string"
				},
				"ContractReview": {
					"type": "string"
				},
				"ProjectInternalId": {
					"type": "string"
				},
				"BeginDate": {
					"type": "string",
					"format": "date-time"
				},
				"FinalDate": {
					"type": "string",
					"format": "date-time"
				},
				"CustomerCode": {
					"type": "string"
				},
				"CustomerInternalId": {
					"type": "string"
				},
				"ContractTotalValue": {
					"type": "number",
					"format": "float"
				},
				"ContractTypeCode": {
					"type": "string"
				},
				"ContractTypeInternalId": {
					"type": "string"
				},
				"ListOfSheet": {
					"type": "array",
					"items": {
						"$ref": "#/definitions/SheetModel"
					}
				}
			},
			"description": "Contrato"
		},
		"SheetModel": {
			"type": "object",
			"properties": {
				"SheetNumber": {
					"type": "string"
				},
				"SheetTypePoperty": {
					"type": "string"
				},
				"UnitPrice": {
					"type": "number",
					"format": "float"
				},
				"SheetTotalValue": {
					"type": "number",
					"format": "float"
				},
				"ListOfItem": {
					"type": "array",
					"items": {
						"$ref": "#/definitions/ItemModel"
					}
				}
			}
		},
		"ItemModel": {
			"type": "object",
			"properties": {
				"ItemCode": {
					"type": "string"
				},
				"ItemInternalId": {
					"type": "string"
				},
				"AccountantAcountCode": {
					"type": "string"
				},
				"AccountantAcountInternalId": {
					"type": "string"
				},
				"CostCenterCode": {
					"type": "string"
				},
				"CostCenterInternalId": {
					"type": "string"
				},
				"AccountingItemCode": {
					"type": "string"
				},
				"AccountingItemInternalId": {
					"type": "string"
				},
				"ClassValueCode": {
					"type": "string"
				},
				"ClassValueInternalId": {
					"type": "string"
				},
				"ItemQuantity": {
					"type": "number",
					"format": "float"
				},
				"ItemUnitPrice": {
					"type": "number",
					"format": "float"
				},
				"ItemTotalValue": {
					"type": "number",
					"format": "float"
				},
				"PercentageOfDiscount": {
					"type": "number",
					"format": "float"
				}
			}
		}
	}
}

Consequentemente, esta segmentação será refletida nos endpoints das APIs. Tomando por base a divisão realizada, teríamos o seguinte template:

/api/{agrupador}/v1/contracts/{ContractUniqueId}/sheets/{SheetNumber}/items/{ItemCode}

Neste template, temos as seguintes considerações:

  • O item ContractUniqueId deve ser um identificador único, já que a entidade Contract prevê uma chave composta. A forma como esta chave será representada ficará a cargo da área de negócio definir. Neste exemplo específico, poderiamos assumir a concatenação dos atributos ContractNumber e ContractReview, separados por "|". Ex: 1|1.
  • No nível de contracts utilizamos o submodelo ContractModel. Nos atributos ListOfSheet e ListOfItem, utilizamos os submodelos SheetModel e ItemModel quando os mesmos forem expandidos.
  • No nível de sheets, utilizamos apenas o submodelo SheetModel. O modelo ItemModel será utilizado quando o atributo ListOfItem for expandido.
  • No nível de items, utilizamos apenas o submodelo ItemModel.
  • Observe a equivalencia entre o item do modelo e o item de path correspondente:
    • ListOfSheet (atributo de ContractModel) equivale a sheets.
    • ListOfItem (atributo de SheetModel) equivale a items.

Nos exemplos a seguir veremos a utilização dos possíveis endpoints e seus respectivos modelos:

Inclusão de um contrato de forma completa

POST /v1/contracts/
{
  "CompanyId": "1",
  "BranchId": "1",
  "CompanyInternalId": "1",
  "InternalId": "1|1|1",
  "ContractNumber": "1",
  "ContractReview": "1",
  "ProjectInternalId": "1|1",
  "BeginDate": "2018-07-25T14:24:00",
  "FinalDate": "2019-07-25T14:24:00",
  "CustomerCode": "1",
  "CustomerInternalId": "1",
  "ContractTotalValue": 1.0,
  "ContractTypeCode": "1",
  "ContractTypeInternalId": "1",
  "ListOfSheet": [{
      "SheetNumber": "1",
      "SheetTypePoperty": "1",
      "UnitPrice": 1.0,
      "SheetTotalValue": 1.0,
      "ListOfItem": [{
          "ItemCode": "1",
          "ItemInternalId": "1|1",
          "AccountantAcountCode": "0001",
          "AccountantAcountInternalId": "1|0001",
          "CostCenterCode": "1",
          "CostCenterInternalId": "1|1",
          "AccountingItemCode": "111",
          "AccountingItemInternalId": "1|111",
          "ClassValueCode": "001",
          "ClassValueInternalId": "1|001",
          "ItemQuantity": 1.0,
          "ItemUnitPrice": 1.0,
          "ItemTotalValue": 1.0,
          "PercentageOfDiscount": 0.0
        }
      ]
    }
  ]
}

Inclusão de um contrato sem folhas (se a regra de negócio permitir)

POST /v1/contracts/
{
  "CompanyId": "1",
  "BranchId": "1",
  "CompanyInternalId": "1",
  "InternalId": "1|1|1",
  "ContractNumber": "1",
  "ContractReview": "1",
  "ProjectInternalId": "1|1",
  "BeginDate": "2018-07-25T14:24:00",
  "FinalDate": "2019-07-25T14:24:00",
  "CustomerCode": "1",
  "CustomerInternalId": "1",
  "ContractTotalValue": 1.0,
  "ContractTypeCode": "1",
  "ContractTypeInternalId": "1",
  "ListOfSheet": []
}

Recuperando contratos (apenas cabeçalho, 1a página, até o limite de uma página)

GET /v1/contracts
{
  "hasNext": false,
  "items": [{
      "_expandables": ["ListOfSheet"],
      "CompanyId": "1",
      "BranchId": "1",
      "CompanyInternalId": "1",
      "InternalId": "1|1|1",
      "ContractNumber": "1",
      "ContractReview": "1",
      "ProjectInternalId": "1|1",
      "BeginDate": "2018-07-25T14:24:00",
      "FinalDate": "2019-07-25T14:24:00",
      "CustomerCode": "1",
      "CustomerInternalId": "1",
      "ContractTotalValue": 1.0,
      "ContractTypeCode": "1",
      "ContractTypeInternalId": "1",
      "ListOfSheet": []
    }
  ]
}

Recuperando um contrato, expandindo os atributos ListOfSheet e ListOfItem

GET /v1/contracts/1|1?expand=ListOfSheet.ListOfItem
{
  "_expandables": ["ListOfSheet"],
  "CompanyId": "1",
  "BranchId": "1",
  "CompanyInternalId": "1",
  "InternalId": "1|1|1",
  "ContractNumber": "1",
  "ContractReview": "1",
  "ProjectInternalId": "1|1",
  "BeginDate": "2018-07-25T14:24:00",
  "FinalDate": "2019-07-25T14:24:00",
  "CustomerCode": "1",
  "CustomerInternalId": "1",
  "ContractTotalValue": 1.0,
  "ContractTypeCode": "1",
  "ContractTypeInternalId": "1",
  "ListOfSheet": [{
      "_expandable": ["ListOfItem"],
      "SheetNumber": "1",
      "SheetTypePoperty": "1",
      "UnitPrice": 1.0,
      "SheetTotalValue": 1.0,
      "ListOfItem": [{
          "ItemCode": "1",
          "ItemInternalId": "1|1",
          "AccountantAcountCode": "0001",
          "AccountantAcountInternalId": "1|0001",
          "CostCenterCode": "1",
          "CostCenterInternalId": "1|1",
          "AccountingItemCode": "111",
          "AccountingItemInternalId": "1|111",
          "ClassValueCode": "001",
          "ClassValueInternalId": "1|001",
          "ItemQuantity": 1.0,
          "ItemUnitPrice": 1.0,
          "ItemTotalValue": 1.0,
          "PercentageOfDiscount": 0.0
        }
      ]
    }
  ]
}

Incluindo uma folha no contrato

POST /v1/contracts/1|1/sheets
{
  "SheetNumber": "1",
  "SheetTypePoperty": "1",
  "UnitPrice": 1.0,
  "SheetTotalValue": 1.0,
  "ListOfItem": [{
      "ItemCode": "1",
      "ItemInternalId": "1|1",
      "AccountantAcountCode": "0001",
      "AccountantAcountInternalId": "1|0001",
      "CostCenterCode": "1",
      "CostCenterInternalId": "1|1",
      "AccountingItemCode": "111",
      "AccountingItemInternalId": "1|111",
      "ClassValueCode": "001",
      "ClassValueInternalId": "1|001",
      "ItemQuantity": 1.0,
      "ItemUnitPrice": 1.0,
      "ItemTotalValue": 1.0,
      "PercentageOfDiscount": 0.0
    }
  ]
}

Incluindo um item de uma folha do contrato

POST /v1/contracts/1|1/sheets/1/items
{
  "ItemCode": "1",
  "ItemInternalId": "1|1",
  "AccountantAcountCode": "0001",
  "AccountantAcountInternalId": "1|0001",
  "CostCenterCode": "1",
  "CostCenterInternalId": "1|1",
  "AccountingItemCode": "111",
  "AccountingItemInternalId": "1|111",
  "ClassValueCode": "001",
  "ClassValueInternalId": "1|001",
  "ItemQuantity": 1.0,
  "ItemUnitPrice": 1.0,
  "ItemTotalValue": 1.0,
  "PercentageOfDiscount": 0.0
}

Eliminando um item de uma folha

  • DELETE /v1/contracts/1|1/sheets/1/items/1

Eliminando uma folha de um contrato

  • DELETE /v1/contracts/1|1/sheets/1

Versionamento da API

O versionamento de APIs que atuam sobre entidades com mensagem padronizada seguirá o padrão definido pelo guia de APIs, sendo independente da versão da mensagem padronizada. Entretanto, mudanças no modelo de dados implicam em mudança no contrato da API e, consequentemente, podem exigir alteração da versão da API.

Segundo o guia de APIs, a versão é composta do seguinte formato:

"v" + majorVersion + "." + minorVersion

onde majorVersion e minorVersion são números inteiros sequenciais, sem "zeros" complementares.

Exemplos de APIs versionadas:

  • /api/financeiro/v1/accountantAccounts
  • /api/educacional/v1.5/disciplines
  • /api/rh/v3.2/employees

As regras para versionamento das APIs, quando relacionadas a mensagem padronizada, são as seguintes:

  • Alterando-se a minorVersion da mensagem padronizada, deve-se alterar a minorVersion da API.
  • Alterando-se a majorVersion da mensagem padronizada, deve-se alterar a majorVersion da API.
  • Inclusão de verbos HTTP, ações ou filtros na API não alteram versão.
  • Alteração de comportamento de endpoint ou na forma de passar os parâmetros alteram versão da API, entretanto não é necessário replicar todos os outros endpoints da API para a nova versão.

Exemplos de versionamento

Para tornar mais claro como versionar as APIs baseadas em mensagem padronizada, colocaremos a seguir um caso de uso.

  • Mensagem padronizada Request, utilizada para CRUD de requisições de estoque ou compras.
  • Mensagem padronizada CancelRequest, utilizada para cancelamento de requisições.

Na versão inicial da API temos os seguintes endpoints, todos baseados na versão 1.000 da transação Request:

APIs v1
GET /api/manufacturing/stock/v1/requests
GET /api/manufacturing/stock/v1/requests/{requestId}
POST /api/manufacturing/stock/v1/requests
PUT /api/manufacturing/stock/v1/requests/{requestId}
DELETE /api/manufacturing/stock/v1/requests/{requestId}

Em um momento posterior, foi liberada a operação de cancelamento da requisição, utilizando a transação CancelRequest, versão 1.000, conforme abaixo:

Novo endpoint na API v1
POST /api/manufacturing/stock/v1/requests/{requestId}/cancelRequest

A API teve mais um endpoint adicionado, porém os demais endpoints não tiveram alteração de contrato. Neste caso, a versão do novo endpoint permanece igual a dos demais.

Consideremos agora, que a API teve alteração na versão da transação Request, evoluindo para a versão 1.001. Neste caso, devemos alterar a versão da API, modificando o minorVersion, conforme segue:

APIs v1.1
GET /api/manufacturing/stock/v1.1/requests
GET /api/manufacturing/stock/v1.1/requests/{requestId}
POST /api/manufacturing/stock/v1.1/requests
PUT /api/manufacturing/stock/v1.1/requests/{requestId}
DELETE /api/manufacturing/stock/v1.1/requests/{requestId}

Agora, teremos disponíveis os seguintes endpoints (observe que o endpoint de cancelamento permaneceu na v1):

Endpoints disponiveis
- V1
GET /api/manufacturing/stock/v1/requests
GET /api/manufacturing/stock/v1/requests/{requestId}
POST /api/manufacturing/stock/v1/requests
PUT /api/manufacturing/stock/v1/requests/{requestId}
DELETE /api/manufacturing/stock/v1/requests/{requestId}
POST /api/manufacturing/stock/v1/requests/{requestId}/cancelRequest
- V1.1
GET /api/manufacturing/stock/v1.1/requests
GET /api/manufacturing/stock/v1.1/requests/{requestId}
POST /api/manufacturing/stock/v1.1/requests
PUT /api/manufacturing/stock/v1.1/requests/{requestId}
DELETE /api/manufacturing/stock/v1.1/requests/{requestId}

Seguindo com o nosso exemplo, vamos considerar agora, que o endpoint de cancelamento precisa, obrigatoriamente, receber um parâmetro de query. Isso altera consideravelmente o comportamento do endpoint. Sendo assim, o incremento deve ocorrer na majorVersion do endpoint, conforme segue.

Novo endpoint v2
POST /api/manufacturing/stock/v2/request/{requestId}/cancelRequest?mandatoryParam=someValue

Com isso, teremos o seguinte cenário de APIs:

Endpoints disponiveis
- v1
GET /api/manufacturing/stock/v1/requests
GET /api/manufacturing/stock/v1/requests/{requestId}
POST /api/manufacturing/stock/v1/requests
PUT /api/manufacturing/stock/v1/requests/{requestId}
DELETE /api/manufacturing/stock/v1/requests/{requestId}
POST /api/manufacturing/stock/v1/requests/{requestId}/cancelRequest
- v1.1
GET /api/manufacturing/stock/v1.1/requests
GET /api/manufacturing/stock/v1.1/requests/{requestId}
POST /api/manufacturing/stock/v1.1/requests
PUT /api/manufacturing/stock/v1.1/requests/{requestId}
DELETE /api/manufacturing/stock/v1.1/requests/{requestId}
- v2
POST /api/manufacturing/stock/v2/request/{requestId}/cancelRequest?mandatoryParam=someValue

Depois de um certo tempo, pode ser necessário reorganizar o cenário das APIs disponíveis, concentrando em uma única versão todas as alterações realizadas. Neste caso, aproveitando a evolução da versão da transação cancelRequest para 2.000 (que afetaria apenas um endpoint), podemos ter uma nova majorVersion abrangendo os demais endpoints da API:

Endpoints disponiveis
- v1
GET /api/manufacturing/stock/v1/requests
GET /api/manufacturing/stock/v1/requests/{requestId}
POST /api/manufacturing/stock/v1/requests
PUT /api/manufacturing/stock/v1/requests/{requestId}
DELETE /api/manufacturing/stock/v1/requests/{requestId}
POST /api/manufacturing/stock/v1/requests/{requestId}/cancelRequest
- v1.1
GET /api/manufacturing/stock/v1.1/requests
GET /api/manufacturing/stock/v1.1/requests/{requestId}
POST /api/manufacturing/stock/v1.1/requests
PUT /api/manufacturing/stock/v1.1/requests/{requestId}
DELETE /api/manufacturing/stock/v1.1/requests/{requestId}
- v2
POST /api/manufacturing/stock/v2/request/{requestId}/cancelRequest?mandatoryParam=someValue
- v3
GET /api/manufacturing/stock/v3/requests
GET /api/manufacturing/stock/v3/requests/{requestId}
POST /api/manufacturing/stock/v3/requests
PUT /api/manufacturing/stock/v3/requests/{requestId}
DELETE /api/manufacturing/stock/v3/requests/{requestId}
POST /api/manufacturing/stock/v3/request/{requestId}/cancelRequest?mandatoryParam=someValue

Ponto de atenção

Após a reorganização da API pode ser necessário excluir a versão anterior e neste caso, a depreciação deve ser feita conforme politica de cada linha de produto.



Links relacionados

Exemplos

Json Schema da Mensagem Branch 2.001 : https://raw.githubusercontent.com/totvs/ttalk-standard-message/master/jsonschema/schemas/Branch_2_001.json

Json Schema dos tipos comuns para APIs : https://github.com/totvs/ttalk-standard-message/blob/master/jsonschema/apis/types/totvsApiTypesBase.json

OpenAPI da API Branch V1.0 : https://raw.githubusercontent.com/totvs/ttalk-standard-message/master/jsonschema/apis/Branch_v1_000.json


TOTVS - Mensagem padronizada e APIs

Portal TOTVS para APIs e Mensagem Padronizada

Guia de implementação de APIs TOTVS

Elaboração de mensagem padronizada REST/JSON

Elaboração de mensagem padronizada SOAP/XML

Repositório de mensagens padronizadas (TFS) - STABLE - requer login TOTVS para acesso.

Repositório de mensagens padronizadas (TFS) - DEV - requer login TOTVS para acesso.

TOTVS - diversos

Mapa de clientes internos TOTVS - lista os Product Owners e demais papeis que devem ser envolvidos no processo de aprovação.

OpenAPI - especificação e ferramentas

Especificação OpenAPI 3.0

Editor Swagger/OpenAPI - permite a criação de documentos Swagger 2.0 ou OpenAPI 3.0 através da edição de tags YAML.

Conversor Swagger 2.0 para OpenAPI - converte um documento Swagger 2.0 em um documento OpenAPI 3.0.

Modelador de APIs Restlet Studio - permite a modelagem de APIs (endpoints, tipos de dados, etc.) gerando documentação em Swagger 2.0 e RAML 1.0.

Padrões internacionais de mensagens para integração

http://docs.oasis-open.org/ubl/prd1-UBL-2.1/UBL-2.1.html

http://docs.oasis-open.org/ubl/UBL-2.1-JSON/v1.0/cnd02/UBL-2.1-JSON-v1.0-cnd02.html

http://docs.oasis-open.org/ubl/UBL-2.1-JSON/v1.0/cnd02/json-schema/maindoc/

http://www.hl7.org/

http://www.unece.org/cefact/brs/brs_index.html

Histórico de Alterações

Version Date Comment
Current Version (v. 35) 22 May, 2019 13:18 Luciano De Araujo:
Cabeçalho redirecionando para o guia de implementação de integrações.
v. 34 14 Nov, 2018 08:51 Francisco Ferreira Cardoso:
Atualizando link para APIs de branch no github
v. 33 03 Oct, 2018 13:45 Luciano De Araujo:
Ajuste de links quebrados para arquivos de exemplo.
v. 32 17 Sep, 2018 16:04 Francisco Ferreira Cardoso:
Removi o Produto da assinatura na URL
v. 31 04 Sep, 2018 12:05 LUCAS PEIXOTO SEPE
v. 30 03 Sep, 2018 19:16 LUCAS PEIXOTO SEPE
v. 29 03 Sep, 2018 18:47 LUCAS PEIXOTO SEPE
v. 28 16 Aug, 2018 14:16 Elvis Leonardo De Oliveira Brito
v. 27 10 Aug, 2018 15:23 Luciano De Araujo
v. 26 10 Aug, 2018 15:21 Luciano De Araujo
v. 25 10 Aug, 2018 15:10 Luciano De Araujo:
Atualizado conforme definições do comitê (reunião de 10/08/2018). Deliberações registradas no link: https://totvs.ryver.com/index.html#posts/1858751
v. 24 01 Aug, 2018 10:18 Luciano De Araujo
v. 23 30 Jul, 2018 16:01 Luciano De Araujo
v. 22 30 Jul, 2018 16:01 Luciano De Araujo
v. 21 30 Jul, 2018 15:29 Luciano De Araujo
v. 20 30 Jul, 2018 14:07 Luciano De Araujo
v. 19 27 Jul, 2018 17:11 Luciano De Araujo
v. 18 27 Jul, 2018 17:07 Luciano De Araujo
v. 17 27 Jul, 2018 16:57 Luciano De Araujo
v. 16 27 Jul, 2018 15:46 Luciano De Araujo
v. 15 27 Jul, 2018 11:22 Luciano De Araujo
v. 14 26 Jul, 2018 17:12 Luciano De Araujo
v. 13 26 Jul, 2018 17:11 Luciano De Araujo
v. 12 26 Jul, 2018 17:04 Luciano De Araujo
v. 11 26 Jul, 2018 16:59 Luciano De Araujo
v. 10 26 Jul, 2018 16:38 Luciano De Araujo:
Atualização das orientações gerais e inclusão de novos links relacionados
v. 9 26 Jul, 2018 10:45 Luciano De Araujo
v. 8 26 Jul, 2018 10:40 Luciano De Araujo
v. 7 26 Jul, 2018 10:38 Luciano De Araujo
v. 6 26 Jul, 2018 10:36 Luciano De Araujo
v. 5 26 Jul, 2018 10:35 Luciano De Araujo
v. 4 26 Jul, 2018 10:32 Luciano De Araujo
v. 3 26 Jul, 2018 09:07 Luciano De Araujo
v. 2 25 Jul, 2018 18:24 Luciano De Araujo
v. 1 25 Jul, 2018 15:16 Luciano De Araujo

{ "$schema": "https://raw.githubusercontent.com/totvs/ttalk-standard-message/master/jsonschema/schemas/events/contract_2_000.json#",
(...), "definitions": { "Contract": { "type": "object", "properties": { "CompanyId": { "type": "string" }, "BranchId": { "type": "string" }, "CompanyInternalId": { "type": "string" }, "InternalId": { "type": "string" }, "ContractNumber": { "type": "string" }, "ContractReview": { "type": "string" }, "ProjectInternalId": { "type": "string" }, "BeginDate": { "type": "string", "format": "date-time" }, "FinalDate": { "type": "string", "format": "date-time" }, "CustomerCode": { "type": "string" }, "CustomerInternalId": { "type": "string" }, "ContractTotalValue": { "type": "number", "format": "float" }, "ContractTypeCode": { "type": "string" }, "ContractTypeInternalId": { "type": "string" }, "ListOfSheet": { "type": "array", "items": { "type": "object", "properties": { "SheetNumber": { "type": "string" }, "SheetTypePoperty": { "type": "string" }, "UnitPrice": { "type": "number", "format": "float" }, "SheetTotalValue": { "type": "number", "format": "float" }, "ListOfItem": { "type": "array", "items": { "type": "object", "properties": { "ItemCode": { "type": "string" }, "ItemInternalId": { "type": "string" }, "AccountantAcountCode": { "type": "string" }, "AccountantAcountInternalId": { "type": "string" }, "CostCenterCode": { "type": "string" }, "CostCenterInternalId": { "type": "string" }, "AccountingItemCode": { "type": "string" }, "AccountingItemInternalId": { "type": "string" }, "ClassValueCode": { "type": "string" }, "ClassValueInternalId": { "type": "string" }, "ItemQuantity": { "type": "number", "format": "float" }, "ItemUnitPrice": { "type": "number", "format": "float" }, "ItemTotalValue": { "type": "number", "format": "float" }, "PercentageOfDiscount": { "type": "number", "format": "float" } } } } } } } }, "description": "Contrato" } }}

Indice