Árvore de páginas

Objetivo


        Apresentar a documentação dos recursos da API Totvs-REST para serem utilizados por outras aplicações do Datasul. Ao oferecer de forma encapsulada esses recursos para que outras aplicações possam acessá-los, torná-se possível o Reuso, a Centralização e Integração:

  • Reuso de lógicas, uma vez que ao expor um método ou uma função  por exemplo, o código do respectivo não precisa ser duplicado no contexto da solução;
  • Centralizar lógica (premissa para coesão) que viabiliza em um único ponto de uma solução o acesso a tal lógica;
  • Viabilizar integração com outras aplicações quando se tata de uma integração em “baixo nível”, o que causa demanda de acesso a recursos internos da aplicação.

    Para modelar a estrutura da documentação será utilizada a ferramenta SWAGGER que, neste contexto faz uso do formato YAML de serialização de dados.

Semântica dos métodos HTTP


        No universo REST, uma requisição HTTP pode-se dizer que é equivalente a uma chamada de uma 'procedure' progress.

O método HTTP é utilizado para determinar a operação a ser realizada em um determinado recurso. Em geral, utiliza-se:

    • GET - método para recuperação de dados,
    • POST - método para para inserir dados,
    • PUT - método para alterar dados existentes e
    • DELETE - método para apagar dados;


Exemplo de Documentação para API Totvs-REST


     O Parser SWAGGER realizará a leitura de um arquivo externo, em formato YAML e validará o conteúdo apontado para um arquivo PROGRESS. O resultado do "parseamento" será um arquivo em formato JSON.

Sobre o SWAGGER:

SWAGGER é uma das principais ferramentas utilizadas para modelagem, documentação e geração de código para APIs do estilo REST. Com ele é possível especificar a descrição de contratos de APIs REST.

Para elucidar a utilização da API Totvs-Rest segue um exemplo de como realizar as chamadas utilizando o 'SWAGGER' para gerar a documentação. Assim, o exemplo seguirá sempre o padrão: Bloco 'SWAGGER' (do arquivo *.yml) seguido de seu bloco 'PROGRESS' correspondente (do arquivo *.p), nesta sequência.

Para o exemplo prático foi utilizada uma simulação de "Manipulação de Pedidos". 

Segue abaixo os blocos de códigos documentados:

INFO

Arquivo *.yml:

Inicialmente é informada a versão do Swagger, na própria seção 'swagger'. Na seção 'info' estão as informações da descrição (description), a versão da API (version) e o título (title).

Na seção basePath colocamos o contexto da aplicação.

Na seção tags se nomeia o serviço (name), a descrição do serviço (description) e os documentos externos (externaldocs), caso existam, com a descrição e o link de acesso (url).

A tag principal desse bloco é 'program' e referencia o arquivo *.p que precisar ser documentado, ou seja, no exemplo abaixo o arquivo *.yml validará o arquivo PROGRESS 'pedido.p'.

swagger: "2.0"
info:
  description: "Este é um exemplo de aplicação de API no modelo Totvs-rest para um modelo de negocio referente a 'Pedidos'"
  version: "1.0.0"
  title: "Exemplo API Totvs-REST" 
basePath: "/tstUn/v1/"
program: pedido.p
tags:
- name: "servicoConsultaPedido"
  description: "Exemplopo de chamada para modelo de negócio 'Pedido'"
  externalDocs:
    description: "Mais informações em:"
    url: "http://tdn.totvs.com"
schemes:
- "http"  
paths:
  /tstUniApiDatasul:


Arquivo *.p:

No bloco de código PROGRESS abaixo (pedido.p), estão inicialmente as chamadas das includes progress referente a padronização das ações dos métodos HTTP. Este trecho não é correspondente ao YAML acima, porém complementa a construção da API TOTVS-REST.

{utp/ut-api.i}
{utp/ut-api-action.i pi-get       GET /~* }
{utp/ut-api-action.i pi-send      GET /~*/SEND by=email,address=~* }
{utp/ut-api-action.i pi-post      POST /~* oi=1}
{utp/ut-api-action.i pi-put       PUT /~* }
{utp/ut-api-action.i pi-delete    DELETE /~* }
{utp/ut-api-notfound.i}

GET

Arquivo *.yml:

A seguir a documentação referente ao método GET para listar os pedidos existentes. A documentação informa que o recurso acessado será "pedido".

Dentro da seção get estão contidas todas a sub seções que compõem a modelagem do recurso desse método (podem haver mais recursos). Assim sendo, na seção tags está definido o path do recurso 'pedido' para montagem da URI: .../tst/v1//tstUniApiDatasul/pedido

Ao enviar a requisição pode-se informar, como parâmentros (na sub seção parameters), filtros do status do  pedido dentro da sub seção items

O retorno da requisição, sub seção produces, será um JSON contendo a lista filtrada dos pedidos existentes na base de dados junto com o status (responses) 200 que informa que a operação foi executada com sucesso.

A validação neste método acontece na declaração da procedure progress, na tag 'procedure', que neste caso é 'pi-get'.

    get:
      procedure: pi-get
      tags:
      - "pedido"
      summary: "Busca Dados dos pedidos existentes"
      description: "Busca os dados dos pedidos cadastrados na base de dados"
      operationId: "getPedido"     
      produces:
      - "application/json"
      parameters:
      - name: "status"
        in: "query"
        description: "Valores de status que precisam ser considerados para o filtro dos pedidos. Ex: available, pending e/ou sold"
        required: true
        type: "array"
        items:
          type: "string"
          enum:
          - "available"
          - "pending"          
          default: "available"
        collectionFormat: "multi"
      responses:
        200:
          description: "Operação executada com sucesso"
          schema:
            type: "array"
            items:
              $ref: "#/definitions/payloadDeRetornoPedido"


Arquivo *.p:

No arquivo progress a procedure correspondente apresenta a efetivação da ação com os dados de entrada e retorno da requisição em um objeto JSON.

PROCEDURE pi-get:

    DEF INPUT  PARAM jsonInput  AS JsonObject NO-UNDO.
    DEF OUTPUT PARAM jsonOutput AS JsonObject NO-UNDO.
    
    ASSIGN jsonOutput = jsonInput.
END.

POST

Arquivo *.yml:

A documentação seguinte refere-se ao cadastro de uma nova informação/registro na base e, para isso, utiliza o método POST.

No mesmo recurso "pedido", serão enviados os dados envelopados em um código JSON (sub seção consumes) e o mesmo será retornado na resposta da requisição (sub seção produces) como comprovação de que os dados foram gravados.

A validação neste método acontece na declaração da procedure progress, na tag 'procedure', que neste caso é 'pi-post'.

    post:
      procedure: pi-post
      tags:
      - "pedido"
      summary: "Cadastro de um novo pedido"
      description: "Envia dados de um novo cadastro de pedido para a base de dados utilizando o método POST"
      operationId: "addPedido"
      consumes:
      - "application/json"
      produces:
      - "application/json"
      parameters:
      - in: "body"
        name: "body"
        description: "Parâmetros necessários enviados no 'payload' para adicionar o novo pedido"
        required: true
        schema:
          $ref: "#/definitions/payloadEnvioPedido"
 


Arquivo *.p:

No arquivo progress a procedure correspondente, assim como no método GET, apresenta a efetivação da ação com os dados de entrada e retorno da requisição em um objeto JSON.

PROCEDURE pi-post:

    DEF INPUT  PARAM jsonInput  AS JsonObject NO-UNDO.
    DEF OUTPUT PARAM jsonOutput AS JsonObject NO-UNDO.
    
    ASSIGN jsonOutput = jsonInput.
END.

PUT

Arquivo *.yml:

A próxima documentação apresenta o método PUT, quando há necessidade de alteração e/ou atualização de algum registro existente.

Assim como o método POST, também encapsula os dados em um código JSON para atualizar os dados desejados (sub seção consumes), porém pode também informar essa atualização como parâmetros na URI.

A validação neste método acontece na declaração da procedure progress, na tag 'procedure', que neste caso é 'pi-put'.

    put:
      procedure: pi-put
      tags:
      - "pedido"
      summary: "Atualiza um registro existente de pedido"
      description: "Atualiza os dados de um registro de pedido existente na base de dados utilizando o método Put"
      operationId: "putPedido"
      consumes:
      - "application/json"      
      produces:
      - "application/json"
      parameters:
      - in: "body"
        name: "body"
        description: "Parâmetros necessários enviados no 'payload' para atualizar um pedido existente"
        required: true
        schema:
          $ref: "#/definitions/payloadEnvioPedido"          


Arquivo *.p:

No arquivo progress a procedure correspondente, assim como no método GET e POST, apresenta a efetivação da ação com os dados de entrada e retorno da requisição em um objeto JSON (sub seção produces).

PROCEDURE pi-put:

    DEF INPUT  PARAM jsonInput  AS JsonObject NO-UNDO.
    DEF OUTPUT PARAM jsonOutput AS JsonObject NO-UNDO.
    
    ASSIGN jsonOutput = jsonInput.
END.

DELETE

Arquivo *.yml:

A documentação para o método DELETE  informa que para executar a exclusão de um registro é preciso passar como parâmetro na URI uma chave na sub seção parameters.

Como retorno, também apresenta um JSON contendo as informações do registro excluído na sub seção produces.

A validação neste método acontece na declaração da procedure progress, na tag 'procedure', que neste caso é 'pi-delete'.

    delete: 
      procedure: pi-delete
      tags:
      - "pedido"
      summary: "Exclui um pedido existente"
      description: "Realiza a exlusão de um pedido existente na base de dados utilizando o método PUT"
      operationId: "deletePedido"
      produces:
      - "application/json"
      parameters:
      - name: "api_key"
        in: "header"
        required: false
        type: "string"
      - name: "petId"
        in: "path"
        description: "Parâmetros necessários enviados no 'payload' para exlcuir um pedido existente"
        required: true
        type: "integer"
        format: "int64"


Arquivo *.p:

No arquivo progress a procedure correspondente, assim como nos métodos anteriores, apresenta a efetivação da ação com os dados de entrada e retorno da requisição em um objeto JSON.

PROCEDURE pi-delete:

    DEF INPUT  PARAM jsonInput  AS JsonObject NO-UNDO.
    DEF OUTPUT PARAM jsonOutput AS JsonObject NO-UNDO.
    
    ASSIGN jsonOutput = jsonInput.
END.

DEFINITIONS

Ainda no arquivo YAML existe a seção definitions onde é realizada a definição do modelo de dados com os objetos, assim sendo, no exemplo abaixo, foram definidos objetos payload para envio  e retorno de pedidos.

Dentro de cada objeto foi estabelecido o tipo (sub seção type) e as propriedades (sub seção properties) pertinentes a cada um.

 definitions:
  payloadEnvioPedido:
    type: "object"
    required:
    - "numeroPedido"
    - "codigoCliente"
    properties:
      id:
        type: "integer"
        format: "int64"
      numeroPedido:
        type: "integer"
        example: "ped123456879"
        format: "int64"
      codigoCliente:
        type: "string"
        description: "cliente1234"
      descricaoCliente:
        type: "string"
        example: "Cliente de Teste"
  payloadDeRetornoPedido:
    type: "object"
    properties:
      id:
        type: "integer"
        format: "int64"
      numeroPedido:
        type: "integer"
        example: "ped123456879"
        format: "int64"
      statusDoPedido:
        type: "string"
        description: "Pedido Aprovado"
        enum:
        - "Aprovado"
        - "Reprovado"  

Restrição:

Comentários tanto em linha (#) com em bloco (/**/) não serão validados, ou seja, o parser realizará a leitura independente da existência ou não dos comentários.

  • Sem rótulos