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.
Informações |
---|
As orientações presentes neste documento estão em constante ajuste. Por isso, consulte sempre esta página quando for modelar uma nova transação. |
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 XML utilizado será Contract_2_000.xsd que está representado graficamente a seguir (clique na imagem para expandir).
Image Modified
Convertendo este modelo "como ele é" para o formato OpenAPI 3.0, teríamos o seguinte documento (alguns elementos previstos no guia de APIs e na elaboração de mensagem padronizada - REST/JSON foram omitidos para melhor compreensão):
Bloco de código | ||||||
---|---|---|---|---|---|---|
| ||||||
{
"openapi": "3.0.0",
(...),
"components": {
"schemas": {
"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 OpenAPI poderia ser segmentado em 3 submodelos:
Convertendo isso para o modelo OpenAPI, teríamos o seguinte, lembrando que elementos como as tags de documentação foram omitidos por questões didáticas.
Bloco de código | ||||||
---|---|---|---|---|---|---|
| ||||||
{
"openapi": "3.0.0",
(...),
"components": {
"schemas": {
"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": "#/components/schemas/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": "#/components/schemas/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:
/v2.000/contracts/{ContractNumber}/sheets/{SheetNumber}/items/{ItemCode}
Neste template, temos as seguintes considerações:
Nos exemplos a seguir veremos a utilização dos possíveis endpoints e seus respectivos modelos:
Inclusão de um contrato de forma completa
Bloco de código | ||||||
---|---|---|---|---|---|---|
| ||||||
{
"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)
Bloco de código | ||||||
---|---|---|---|---|---|---|
| ||||||
{
"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)
Bloco de código | ||||||
---|---|---|---|---|---|---|
| ||||||
{
"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
Bloco de código | ||||||
---|---|---|---|---|---|---|
| ||||||
{
"_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
Bloco de código | ||||||
---|---|---|---|---|---|---|
| ||||||
{
"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
Bloco de código | ||||||
---|---|---|---|---|---|---|
| ||||||
{
"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
Eliminando uma folha de um contrato
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
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.
Índice |
---|