Histórico da Página
...
Exemplos |
---|
canUpdate: true canUpdate: false |
Campo Obrigatório
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 repositório do 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 Contract_2_000.json, 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):
Bloco de código | ||||
---|---|---|---|---|
| ||||
{
"$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.
Bloco de código | ||||
---|---|---|---|---|
| ||||
{
"$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:
Bloco de código | ||
---|---|---|
| ||
/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 SheetModele 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
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
- DELETE /v1/contracts/1|1/sheets/1/items/1
Eliminando uma folha de um contrato
- DELETE /v1/contracts/1|1/sheets/1
Âncora | ||||
---|---|---|---|---|
|
...