Como Criar APIs RestFull em Dataflex: Guia Completo com Web API Framework e Swagger UI

ÍNDICE

  1. Introdução
  2. O que é o Web API Framework do Dataflex
  3. Configuração Inicial: Criando a API Principal
    3.1 Análise da Configuração Principal
  4. Criando o Primeiro Endpoint: Inventário
    4.1 Compreendendo a Estrutura do Endpoint
    4.2 Definindo Campos com cRestField
    4.3 Operações REST Automáticas
  5. Endpoint Avançado: Gerenciamento de Clientes com Relacionamentos
    5.1 Compreendendo Relacionamentos Complexos
    5.2 cRestChildCollection: Expondo Relacionamentos Um-para-Muitos
    5.3 cRestEntity: Dados de Tabelas Relacionadas
  6. Implementando Swagger UI: Documentação Interativa
    6.1 Configurando a View do Swagger UI
    6.2 Recursos da Interface Swagger UI
    6.3 Geração Automática da Especificação OpenAPI
    6.4 Personalizando a Documentação
  7. Testando a API através do Swagger UI
    7.1 Testando Operações CRUD
    7.2 Testando Relacionamentos Complexos
  8. Versionamento de APIs com Roteadores
    8.1 Estratégia de Versionamento
    8.2 Migração Entre Versões
  9. Melhores Práticas para APIs Dataflex
    9.1 Segurança e Autenticação
    9.2 Validação e Tratamento de Erros
    9.3 Performance e Otimização
  10. Estrutura de Resposta JSON
  11. Integração com Ferramentas de Desenvolvimento
    11.1 Postman e Insomnia
    11.2 Geração de Código Cliente
  12. Casos de Uso Avançados
    12.1 Integração com Sistemas Externos
    12.2 Aplicações Mobile
    12.3 Microserviços e Arquiteturas Distribuídas

As APIs RestFull se tornaram o idioma comum entre sistemas. Se a sua base é Dataflex, a boa notícia é que já existe um caminho rápido, seguro e moderno para expor dados e processos: o Web API Framework, com documentação automática via Swagger UI. Neste guia, você verá, passo a passo, como criar endpoints, versionar sua API, testar tudo no navegador e adotar boas práticas que aceleram o time-to-market sem abrir mão da robustez do Dataflex.

O que é o Web API Framework do Dataflex

O Web API Framework é uma biblioteca (open source) que facilita a criação de APIs RestFull em Dataflex usando conceitos familiares e gerando OpenAPI automaticamente. Assim, sua documentação está sempre sincronizada com o código e pode ser consumida por Swagger UI, Postman e afins. Na prática, você modela dados com o que já domina e publica endpoints REST prontos para integração.

Tela do Dataflex Studio com recurso de arrastar e soltar para criar endpoints de APIs RestFull.

Configuração Inicial: Criando a API Principal

O primeiro passo é declarar a “porta de entrada” da API com a classe cWebApi, definir o path base (ex.: /Api), registrar iteradores (JSON/XML) e configurar roteadores para versionamento (ex.: /Api/v1 e /Api/v2).


 //File -> New -> Web Object -> Web HTTP Handler
 //Novo código para usar a WebAPI
 Use WebApi\cWebApi.pkg
 Use WebApi\cWebApiRouter.pkg
 Use cBasicAuth.pkg
 
 //Usar o Primeiro OpenApiEndpoint aqui
 Object oExampleRestAPI is a cWebApi
     // Configurar path base da API
     Set psPath to "Api"
     
     //Tenha em mente que o primeiro iterador que você registrar no objeto cWebApi será o padrão.
     //Então, se alguém enviar uma solicitação com um accept-type ou content-type não suportado, será usado o primeiro iterador como padrão.
     Send AddIterator (RefClass(cJSONIterator)) "application/json"
     Send AddIterator (RefClass(cXMLIterator)) "application/xml"
     
     // Router para versão 1 da API
     Object oV1Router is a cWebApiRouter
         Set psPath to "v1"
         
         // Endpoints da versão 1
         Use FirstEndPoint.pkg
     End_Object//oV1Router

     // Router para versão 2 da API
     Object oV2Router is a cWebApiRouter
         Set psPath to "v2"
         
         // Endpoints da versão 2
         Use CustomerEndPoint.pkg
     End_Object//oV2Router
 End_Object//oExampleRestAPI
 

Análise da Configuração Principal

  • psPath “Api”: estabelece o caminho base da API.
  • Iteradores (JSON/XML): priorize JSON como padrão; isso melhora DX e integrações.
  • Roteadores por versão: isola v1 e v2, permitindo evoluir sem quebrar clientes existentes.

Criando o Primeiro Endpoint: Inventário

O endpoint de Inventário é um ótimo exemplo introdutório: simples, direto e completo.

//Criado da seguinte forma:
//Importar a classe cRestDataset
Use WebApi\cRestDataset.pkg
//Adicionar o DD do Inventario
Use cInventoryDataDictionary.dd
Use WebApi\cRestField.pkg

//Declarar o Objeto usando a classe cRestDataset
Object oFirstEndpoint is a cRestDataset
    Set psPath to "Inventory"
    Set pbSecureRead to False
    
    Object oInventory_DD is a cInventoryDataDictionary
    End_Object//oInventory_DD

    Set Main_DD to oInventory_DD
    Set Server to oInventory_DD

    // Campo ID do Item (somente leitura)
    Object oInventory_Item_ID is a cRestField
        Set pbReadOnly to True
        Entry_Item Inventory.Item_ID
    End_Object
    
    // Campo Descrição
    Object oInventory_Description is a cRestField
        Entry_Item Inventory.Description
    End_Object
    
    // Campo Preço Unitário
    Object oInventory_Unit_Price is a cRestField
        Entry_Item Inventory.Unit_Price
    End_Object
    
    // Campo Quantidade em Estoque
    Object oInventory_On_Hand is a cRestField
        Entry_Item Inventory.On_Hand
    End_Object
    
End_Object//oFirstEndpoint

Compreendendo a Estrutura do Endpoint

Use cRestDataset para expor dados tabulares. Com psPath “Inventory”, o recurso ficará em /Api/v1/Inventory. Ao vincular um Data Dictionary (Main_DD, Server), você reaproveita regras de negócio e validações existentes no Dataflex.

Definindo Campos com cRestField

Declare um cRestField por campo exposto:

  • IDs geralmente ficam pbReadOnly = True.
  • Campos de negócio (Description, Unit_Price, On_Hand) mapeados com Entry_Item garantem coerência entre API e base.

Operações REST Automáticas

Com a configuração, o framework entrega out-of-the-box:

  • GET /Api/v1/Inventory e /Api/v1/Inventory/{id}
  • POST /Api/v1/Inventory
  • PUT/PATCH /Api/v1/Inventory/{id}
  • DELETE /Api/v1/Inventory/{id}

Exemplo no Postman com requisição GET para endpoint de inventário em uma API RestFull Dataflex.

Endpoint Avançado: Gerenciamento de Clientes com Relacionamentos

Agora, vamos além, expondo relacionamentos (cliente → pedidos → itens → estoque).

//Criado da seguinte forma:
//Importar a classe cRestDataset
Use WebApi\cRestDataset.pkg
//Adicionar o DD do Inventario
Use cCustomerDataDictionary.dd
Use cSalesPersonDataDictionary.dd
Use cOrderHeaderDataDictionary.dd
Use cVendorDataDictionary.dd
Use cInventoryDataDictionary.dd
Use cOrderDetailDataDictionary.dd
Use WebApi\cRestField.pkg


//Declarar o Objeto usando a classe cRestDataset
Object oCustomerEndpoint is a cRestDataset
    Set psPath to "Customer"
    Set pbSecureRead to False

    Object oVendor_DD is a cVendorDataDictionary
    End_Object

    Object oInventory_DD is a cInventoryDataDictionary
        Set DDO_Server to oVendor_DD
    End_Object

    Object oSalesPerson_DD is a cSalesPersonDataDictionary
    End_Object

    Object oCustomer_DD is a cCustomerDataDictionary
    End_Object

    Object oOrderHeader_DD is a cOrderHeaderDataDictionary
        Set DDO_Server to oSalesPerson_DD
        Set Constrain_file to Customer.File_number
        Set DDO_Server to oCustomer_DD
    End_Object

    Object oOrderDetail_DD is a cOrderDetailDataDictionary
        Set DDO_Server to oInventory_DD
        Set Constrain_file to OrderHeader.File_number
        Set DDO_Server to oOrderHeader_DD
    End_Object

    Set Main_DD to oCustomer_DD
    Set Server to oCustomer_DD

    // Campo ID do Customer (somente leitura)
    Object oCustomer_Customer is a cRestField
        Set pbReadOnly to True
        Entry_Item Customer.Customer_Number
    End_Object
    
    // Campo Name
    Object oCustomer_Name is a cRestField
        Entry_Item Customer.Name
    End_Object

    // Campo Address
    Object oCustomer_Address is a cRestField
        Entry_Item Customer.Address
    End_Object

    // Campo City
    Object oCustomer_City is a cRestField
        Entry_Item Customer.City
    End_Object
    
    // Campo State
    Object oCustomer_State is a cRestField
        Entry_Item Customer.State
    End_Object

    // Campo EMail_Address
    Object oCustomer_EMail_Address is a cRestField
        Entry_Item Customer.EMail_Address
    End_Object

    //Elemento OrderHeader
    Object oOrderHeaderEntity is a cRestChildCollection
        Set Server to oOrderHeader_DD

        // Campo ID do Order_Number (somente leitura)
        Object oOrderHeader_Order_Number is a cRestField
            Set pbReadOnly to True
            Entry_Item OrderHeader.Order_Number
        End_Object       

        // Campo Order_Date
        Object oOrderHeader_Date is a cRestField
            Entry_Item OrderHeader.Order_Date
        End_Object    

        // Campo Terms
        Object oOrderHeader_Terms is a cRestField
            Entry_Item OrderHeader.Terms
        End_Object    

        // Campo Ship_Via
        Object oOrderHeader_Ship_Via is a cRestField
            Entry_Item OrderHeader.Ship_Via
        End_Object

        // Campo Order_Total
        Object oOrderHeader_Order_Total is a cRestField
            Entry_Item OrderHeader.Order_Total
        End_Object 
        
        //Elemento SalesPerson
        Object oSalesPersonEntity is a cRestEntity
            Set Server to oSalesPerson_DD
            
            // Campo ID do SalesPerson (somente leitura)
            Object oSalesPerson_ID is a cRestField
                Set pbReadOnly to True
                Entry_Item SalesPerson.ID
            End_Object                   

            // Campo Name (somente leitura)
            Object oSalesPerson_Name is a cRestField
                Set pbReadOnly to True
                Entry_Item SalesPerson.Name
            End_Object   
            
        End_Object//oSalesPersonEntity
        
        //Elemento OrderDetail
        Object oOrderDetailEntity is a cRestChildCollection
            Set Server to oOrderDetail_DD

            // Campo ID do Detail_Number (somente leitura)
            Object oOrderDetail_Numeber is a cRestField
                Set pbReadOnly to True
                Entry_Item OrderDetail.Detail_Number
            End_Object         

            // Campo ID do Item_ID (somente leitura)
            Object oOrderDetail_Item_ID is a cRestField
                Set pbReadOnly to True
                Entry_Item OrderDetail.Item_ID
            End_Object   

            // Campo ID do Item_ID (somente leitura)
            Object oInventory_Description is a cRestField
                Set pbReadOnly to True
                Entry_Item Inventory.Description
                Set Server to oInventory_DD
            End_Object   

            // Campo Qty_Ordered (somente leitura)
            Object oOrderDetail_Qty_Ordered is a cRestField
                Set pbReadOnly to True
                Entry_Item OrderDetail.Qty_Ordered
            End_Object   

            // Campo Price (somente leitura)
            Object oOrderDetail_Price is a cRestField
                Set pbReadOnly to True
                Entry_Item OrderDetail.Price
            End_Object   

            // Campo Extended_Price (somente leitura)
            Object oOrderDetail_Extended_Price is a cRestField
                Set pbReadOnly to True
                Entry_Item OrderDetail.Extended_Price
            End_Object  
        
        End_Object//oOrderDetailEntity
        
    End_Object//oOrderHeaderEntity
End_Object//oCustomerEndpoint

Compreendendo Relacionamentos Complexos

Com múltiplos Data Dictionaries e constraints, o framework navega pelas relações e monta uma resposta única e coerente, mantendo a integridade referencial.

cRestChildCollection: Expondo Relacionamentos Um-para-Muitos

Use cRestChildCollection para retornar coleções (ex.: Pedidos de um Cliente). O resultado é um JSON com arrays aninhadas.

cRestEntity: Dados de Tabelas Relacionadas

Quando precisar incluir um objeto relacionado (ex.: Vendedor do pedido), utilize cRestEntity para embutir o “muitos-para-um” como objeto dentro do recurso pai.

Implementando Swagger UI: Documentação Interativa

O Swagger UI lê a especificação OpenAPI gerada automaticamente e exibe uma interface interativa para explorar e testar a API no navegador.

Configurando a View do Swagger UI

Implemente uma cWebView com o controle cSwaggerUI apontando para o endpoint da spec (ex.: /Api/OpenApi).

//Exemplo SwaggerUI
Use cWebView.pkg
Use cWebPanel.pkg
Use WebApi\cSwaggerUI.pkg

Object oOpenApiView is a cWebView
    Set psCaption to "OpenApiSpecification"
    Set pbShowCaption to False
    
    Set phoDefaultView to Self

    Object oWebMainPanel is a cWebPanel
        Set piColumnCount to 24
        
        Object oSwaggerUI is a cSwaggerUI
            Set piColumnSpan to 10
            Set pbShowLabel to False
            Set piColumnIndex to 5
            
            Set psOpenApiUrl to "/Api/OpenApi"
        End_Object//oSwaggerUI
        
    End_Object //oWebMainPanel

End_Object//oOpenApiView

Recursos da Interface Swagger UI

  • Exploração de endpoints (métodos, parâmetros, schemas)
  • Try it out: testes reais sem sair do browser
  • Schemas detalhados: tipos, obrigatoriedades e exemplos
  • Códigos de resposta: sucesso, validação e erros

Geração Automática da Especificação OpenAPI

O framework varre os endpoints, campos e relacionamentos, gerando a OpenAPI sempre atualizada, nada de documentação desatualizada.

Personalizando a Documentação

Descreva endpoints e campos com psDescription, psTag e psSummary. Adicione exemplos e notas, melhore a DX e facilite a integração de terceiros.

Testando a API através do Swagger UI

Além de documentar, o Swagger UI acelera o ciclo de desenvolvimento.

Testando Operações CRUD

  • GET lista/busca
  • POST cria
  • PUT/PATCH atualiza
  • DELETE exclui
    Com formulários gerados automaticamente e validação inline.

Testando Relacionamentos Complexos

Chame, por exemplo, GET /Api/v2/Customer/{id} e visualize cliente, pedidos e itens em uma única resposta, ótimo para validar joins e constraints.

Resposta JSON complexa no Swagger UI com dados relacionados de uma API RestFull Dataflex.

Versionamento de APIs com Roteadores

Versões separadas evitam breaking changes e dão previsibilidade.

Estratégia de Versionamento

  • v1: endpoints base (ex.: Inventário)
  • v2: relacionamentos avançados (ex.: Clientes/Pedidos)
    URLs distintas (/Api/v1 vs /Api/v2) e documentação segregada.

Migração Entre Versões

Implemente recursos novos em v2, mantenha v1 até que os consumidores migrem. Depois, descontinue com segurança.

Melhores Práticas para APIs Dataflex

Segurança e Autenticação

  • Prefira JWT Bearer para produção.
  • Aplique autenticação de forma consistente.
  • Restrinja endpoints sensíveis; avalie pbSecureRead com cuidado.

Validação e Tratamento de Erros

  • Combine validações do Data Dictionary com regras específicas da API.
  • Retorne HTTP codes adequados e mensagens claras (UX de dev conta muito).

Performance e Otimização

  • Implemente paginação e filtros.
  • Se necessário, crie endpoints focados (nem todo cenário precisa de todas as coleções aninhadas).
  • Cacheie respostas estáveis quando fizer sentido.

Estrutura de Resposta JSON

Tenha clareza de como o framework serializa respostas.

[
  {
    "Item Id": "ACE-2",
    "Description": "More Ace Stuff",
    "Unit Price": 39,
    "On Hand": 89
  },
  {
    "Item Id": "CASE",
    "Description": "Understanding Case Technology",
    "Unit Price": 39,
    "On Hand": 707
  },
  {
    "Item Id": "JOKES",
    "Description": "The Best of Computer Humor",
    "Unit Price": 39,
    "On Hand": 590
  },
  {
    "Item Id": "OFFICE-2",
    "Description": "Office Communication Methods",
    "Unit Price": 39,
    "On Hand": 577
  }
]
[
  {
    "Customer Number": 1,
    "Name": "Access Miles",
    "Address": "1400 NW 190 Ave",
    "City": "Miami",
    "State": "FL",
    "Email Address": "customerservice@amiles.com",
    "OrderHeader": [
      {
        "Order Number": 113,
        "Order Date": "22/10/2020",
        "Terms": "NET30",
        "Ship Via": "UPS",
        "Order Total": 2766,
        "SalesPerson": {
          "Id": "TT",
          "Name": "Tina Tompson"
        },
        "OrderDetail": [
          {
            "Detail Number": 2,
            "Item Id": "UPDATE",
            "Description": "How to Update Your Own Computer",
            "Qty Ordered": 1,
            "Price": 19,
            "Extended Price": 19
          },
          {
            "Detail Number": 3,
            "Item Id": "JOKES",
            "Description": "The Best of Computer Humor",
            "Qty Ordered": 5,
            "Price": 12,
            "Extended Price": 60
          },
          {
            "Detail Number": 4,
            "Item Id": "TEXT-ALL",
            "Description": "Computers Made Easy, Boxed Set",
            "Qty Ordered": 2,
            "Price": 595,
            "Extended Price": 1190
          },
          {
            "Detail Number": 5,
            "Item Id": "UNIXGUIDE",
            "Description": "The Complete Unix Guide. Vol 1",
            "Qty Ordered": 3,
            "Price": 499,
            "Extended Price": 1497
          }
        ]
      },
      {
        "Order Number": 114,
        "Order Date": "24/10/2020",
        "Terms": "PREPAY",
        "Ship Via": "UPS",
        "Order Total": 328,
        "SalesPerson": {
          "Id": "CM",
          "Name": "Carlos Montero"
        },
        "OrderDetail": [
          {
            "Detail Number": 2,
            "Item Id": "MODEMS",
            "Description": "The Modem User's Fun-Kit",
            "Qty Ordered": 1,
            "Price": 129,
            "Extended Price": 129
          },
          {
            "Detail Number": 3,
            "Item Id": "REPORTS II",
            "Description": "The Top 5,000 Reports in Government",
            "Qty Ordered": 1,
            "Price": 199,
            "Extended Price": 199
          }
        ]
      }
      // ... mais pedidos seguem o mesmo padrão ...
    ]
  }
]

Integração com Ferramentas de Desenvolvimento

Postman e Insomnia

Importe a OpenAPI e gere coleções com requests prontas (ambientes dev/homolog/prod ajudam muito no fluxo de testes).

Geração de Código Cliente

Use Swagger Codegen/OpenAPI Generator para criar SDKs em JS, Python, C#, Java etc. Isso acelera a integração de parceiros e times internos.

Casos de Uso Avançados

Integração com Sistemas Externos

Exponha dados legados Dataflex via REST e conecte com ERPs/CRMs e plataformas web, modernização gradual e segura.

Aplicações Mobile

Consuma JSON diretamente em iOS/Android. A doc do Swagger UI diminui fricção entre squads.

Microserviços e Arquiteturas Distribuídas

Separe domínios por serviços, evolua versões de forma independente e mantenha o ecossistema coeso com roteadores e documentação clara.

Se você precisa abrir seu Dataflex para o mundo REST, o Web API Framework oferece o atalho certo: APIs RestFull com menos código, mais padrão e documentação automática. Com versionamento via roteadores, Swagger UI e boas práticas de segurança/performance, sua equipe entrega rápido, com qualidade e sem surpresas.

Precisa desenvolver uma API robusta em Dataflex? Solicite um orçamento com a Streamsoft



Referências:

[1] DataFlex Web API Framework – GitHub Repository. Disponível em: https://github.com/DataFlex-dev/Web-API-Framework

[2] OpenAPI Specification. Disponível em: https://swagger.io/specification/

[3] Swagger UI Documentation. Disponível em: https://swagger.io/tools/swagger-ui/

[4] REST API Design Best Practices. Disponível em: https://restfulapi.net/

[5] DataFlex Documentation. Disponível em: https://docs.dataaccess.com/

Últimas Postagens

Pronto para levar seu projeto ao próximo nível?