Árvore de páginas

Versões comparadas

Chave

  • Esta linha foi adicionada.
  • Esta linha foi removida.
  • A formatação mudou.
Informações
titleÍndice

Índice
maxLevel1
excludeOu seja,

Introdução


O desenvolvimento de APIs permite a exposição e o consumo de dados com o objetivo da integração front-end (portais, customizações, etc) ao back-end do produto Datasul, de maneira segura e padronizada.

A estrutura de integração de APIs Datasul suporta o envio de requisições no estilo de arquitetura REST com o desenvolvimento da regra de negócio em Progress. 


Abaixo o fluxo das requisições via HTTP (DATASUL-REST) e formato de execução via Progress:



Esta funcionalidade está disponível para utilização conforme apresentado no quadro abaixo:

Informações
titleMatriz de Evolução


draw.io Diagram
bordertrue
viewerToolbartrue
fitWindowfalse
diagramNamereleases
simpleViewerfalse
width
diagramWidth926
revision78


Contextos


Expandir
titleClick para visualizar o conteúdo

Existem 2 contextos definidos que se aplicam tanto para a Antiga arquitetura (Jboss) quanto para o DTS4THF (Tomcat).

Estes contextos tem o objetivo de definir o acesso das requisições, ou seja, se são contextos de acessos internos (via menu) pelo contexto DTS/DATASUL-REST ou acessos externos (via APPs por exemplo) pelo contexto /API.

draw.io Diagram
bordertrue
viewerToolbartrue
fitWindowfalse
diagramNamecontextos
simpleViewerfalse
diagramWidth935
revision2


Card documentos
InformacaoO contexto /api foi criado com autenticação via "Basic Authentication", para atender o guia de API TOTVS, sendo possível conexão com qualquer API que anteriormente era "dts/datasul-rest/resources/prg".
TituloIMPORTANTE!




Formato URL


Expandir
titleClique para visualizar o conteúdo

O Guia de Implementação de API TOTVS define que no formato das URIs dos endpoints deve conter:

  • o nome do produto;
  • o módulo;
  • a versão da API;
  • o recurso alvo da funcionalidade em questão.

Modelo de acesso aos Contextos:


Informações
iconfalse
title/prg

Tomando como exemplo o endpoint de integração do recurso de "Usuários" do aplicativo "Foundation" do produto "Datasul", a URI básica deste serviço deve ser: /prg/sec/v1/users

Para o produto Datasul, o serviço responsável é implementado no contexto /dts/datasul-rest/

Desta forma, a URL final do serviço exemplo acima seria composta da seguinte maneira: 



Aviso

A URL definida pelo Padrão de API TOTVS segue o seguinte formato:

/dts/datasul-rest/resouces/prg/<módulo>/<versão API>/<recurso>/

Informações que forem passadas após o recurso, serão tratadas como parâmetros PATH.


Informações
iconfalse
title/api

Para exemplo do funcionamento /api vamos utilizar o mesmo recurso de integração de usuário exemplificado anteriormente.

URI deste serviço deve ser: /api/sec/v1/users

No geral o funcionamento do /api é igual ao /prg, com a ressalva de que o endpoint /api não esta dentro do contexto /dts/datasul-rest/



Aviso

A URL definida pelo Padrão de API TOTVS segue o seguinte formato:

/api/<módulo>/<versão API>/<recurso>/

Informações que forem passadas após o recurso, serão tratadas como parâmetros PATH.




Serviço Progress


Expandir
titleClique para visualizar o conteúdo

Para "publicar" a funcionalidade Progress ABL basta criar o programa (.p) com o seguinte caminho: sec/api/v1/users.p (<módulo>/api/<versão API>/<recurso>.p). 

Nota
iconfalse
O arquivo *.p é  o fonte original de criação da API, porém para sua real utilização é preciso compilá-lo para se transformar em um arquivo *.r.


A sub-pasta "api" passa então a concentrar todas as funcionalidades de integração do módulo em questão:

Aviso

Os programas Progress disponibilizados, deverão seguir o padrão de localização abaixo e devem estar compilados, ou seja, é necessário o *.r:

<módulo>/api/<versão API>/<recurso>.r


OBS: Outros caminhos e parâmetros podem ser adicionados a URL, mas sempre de acordo com o Guia de Implementação de APIs.


     O Guia de Implementação de API TOTVS define também que a troca de mensagens é feita (impreterivelmente) no formato JSON, e por conta disso, a troca de mensagens com as funcionalidades Progress também devem ser feitas nesse formato, mais especificamente por meio de um parâmetro de entrada e outro de saída do tipo LONGCHAR que devem ser devidamente tratados (parseados e formatados) pela funcionalidade utilizando as includes utilitárias disponibilizadas:

  • utp/ut-api.i: Faz o parser do parâmetro LONGCHAR de entrada e cria um objeto JsonObject chamado jsonInput.
  • utp/ut-api-action.i: Faz o roteamento do objecto jsonInput para uma procedure interna especificada pelo desenvolvedor.
  • utp/ut-api-notfound.i: Caso nenhuma procedure interna tenha sido encontrada, retorna uma mensagem "Method not found" com HTTP Status 400.

>>>>>Abaixo um exemplo de recurso desenvolvido em Progress ABL para ser utilizado junto ao serviço de API<<<<<<

Expandir
titleClique para visualizar o exemplo ...

No início do código estão todas as includes necessárias. O que vale ressaltar neste trecho é referente a include ut-api-action:

  • Nesta include são declaradas as procedures utilizadas na API, por exemplo: pi-send, pi-update.
  • Na mesma declaração é definido qual o método http aplicado, por exemplo: GET, POST, entre outros.
  • Em seguida é definido como o recurso será acessado pela URI, por exemplo: /~*/SEND
  • Isso significa que ao acessar a URI teremos algo como: http://host:port/dts/datasul-rest/resources/prg/sec/v1/users/send onde:


 

draw.io Diagram
bordertrue
viewerToolbartrue
fitWindowfalse
diagramNameestrutura
simpleViewerfalse
width600
linksauto
tbstyletop
lboxtrue
diagramWidth785
revision5


Bloco de código
languageruby
themeEclipse
{utp/ut-api.i}
{utp/ut-api-action.i pi-send    GET /~*/SEND by=email,address=~* }
{utp/ut-api-action.i pi-update  POST /~* }
{utp/ut-api-action.i pi-find    GET /~* }
{utp/ut-api-action.i pi-default GET }
{utp/ut-api-notfound.i}
  
PROCEDURE pi-send:
    DEF INPUT PARAM jsonInput AS JsonObject NO-UNDO.
    DEF OUTPUT PARAM jsonOutput AS JsonObject NO-UNDO.
     
    DEFINE VARIABLE aJsonArray  AS JsonArray  NO-UNDO.
    DEFINE VARIABLE oJsonObject AS JsonObject NO-UNDO.
 
    aJsonArray = NEW JSONArray().
 
    oJsonObject = NEW JSONObject().
    oJsonObject:ADD("teste", "teste").
    oJsonObject:ADD("teste1", "teste1").
    oJsonObject:ADD("teste2", "teste2").
    aJsonArray:ADD(oJsonObject).
 
    oJsonObject = NEW JSONObject().
    oJsonObject:ADD("teste", "teste").
    oJsonObject:ADD("teste1", "teste1").
    oJsonObject:ADD("teste2", "teste2").
    aJsonArray:ADD(oJsonObject).
 
    jsonOutput = JsonAPIResponseBuilder:ok(aJsonArray, false).
END.
  
PROCEDURE pi-update:
    DEF INPUT PARAM jsonInput AS JsonObject NO-UNDO.
    DEF OUTPUT PARAM jsonOutput AS JsonObject NO-UNDO.

    jsonOutput = NEW JSONObject().
    jsonOutput = jsonInput.
END.
 
PROCEDURE pi-find:
    DEF INPUT PARAM jsonInput AS JsonObject NO-UNDO.
    DEF OUTPUT PARAM jsonOutput AS JsonObject NO-UNDO.
    
    jsonOutput = NEW JSONObject().
    jsonOutput:ADD("method", "GET").
    jsonOutput:ADD("procedure", "pi-find").
    jsonOutput:ADD("description", "Test").
END.

PROCEDURE pi-default:
    DEF INPUT PARAM jsonInput AS JsonObject NO-UNDO.
    DEF OUTPUT PARAM jsonOutput AS JsonObject NO-UNDO.
    
    jsonOutput = NEW JSONObject().
    jsonOutput:ADD("method", "GET").
    jsonOutput:ADD("procedure", "pi-default").
    jsonOutput:ADD("description", "Test").
END.


     No exemplo acima, temos as seguintes includes utilitárias:

draw.io Diagram
bordertrue
viewerToolbartrue
fitWindowfalse
diagramNameutilitarios
simpleViewerfalse
diagramWidth1079
revision5



Informações

Algumas considerações sobre o uso da include de roteamento (ut-api-action):

  • Os roteamentos devem ser definidos do mais específico (detalhado) para o mais genérico (simples);
  • O utilitário faz uso da função MATCHES do Progress, que basicamente permite o uso do ponto "." (ponto) como coringa de uma determinada posição (1 caractere apenas) e o "*" (asterisco) para um conjunto de caracteres variáveis;
  • O caracter de escape "~" deve ser utilizado sempre que necessário, antecedendo caracteres especiais que comprometam a compilação do código progress;
  • Para definir mais de um parâmetro de pesquisa, utilize "," (vírgula) como separador. O processamento de mais de um parâmetro de pesquisa será sempre traduzido para usar o operador AND.
  • Permite o uso de todos métodos HTTP suportados pelo API Manager (GET, POST, PUT, DELETE, PATCH, ...)
Informações

A include ut-api.i precisa ser adicionada obrigatoriamente no início do programa Progress, visto que esta include faz uso da instrução USING para importação de classes. Portanto, devido a esta caraterística do Progress ABL, somente será possível adicionar outras includes depois da adição da ut-api.i e ut-api-notfound.i, respectivamente.



Classes utilitárias


Expandir
titleClique para visualizar o conteúdo

Com o objetivo de facilitar a manipulação dos objetos JsonObject recebidos e enviados pela API Progress foram desenvolvidas algumas classes de utilitários:

  • JsonAPIRequestParser - Extrai informações do objeto JSON recebido como parâmetro da requisição.
  • JsonAPIResponse - Trata a criação do objeto JSON de response da requisição.
  • JsonAPIResponseBuilder - Trata a criação do objeto JSON de response da requisição através de um builder.
  • JsonAPIUtils - Utilitário com métodos que facilitam a manipulação de informações relacionados a API



Formato Mensagem JSON


Expandir
titleClique para visualizar o conteúdo

O objeto JsonObject, recebido pela requisição no programa Progress conterá informações completas da requisição, desde informações do:

  • HEADER;
  • QUERY PARAMs;
  • PATH PARAMs;
  • o próprio PAYLOAD e;
  • arquivos MULTIPART.

Com esta mensagem, o desenvolvedor poderá efetuar os devidos filtros e classes utilitárias necessárias. 

Exemplo de mensagem:

Bloco de código
languageyml
themeEclipse
linenumberstrue
{ 
    uri: valor,
	method: GET,
    headers: {},
	pathParams: [ "param1", "param2" ],
	queryParams: { query1: [valor1, valor2], query2: [valor1]},
	payload: { },
	multyPartFile: [ {file: ...}, {file: ...}]
}



Login


Expandir
titleClique para visualizar o conteúdo
Expandir
titleAntiga Arquitetura (JBOSS)

Na Antiga Arquitetura (Jboss) para realizar o login no contexto DTS/DATASUL-REST (apesar de existir BASIC AUTHENTICATION com o contexto /api), ainda é possível passar como parâmetro usuário e senha para na seguinte URL.

Dica
titleURL para Login

http://localhost:8180/dts/datasul-rest/resources/login?username=<USER>&password=<PASSWORD>


Para passagem da senha deve ser em Lower Case e é necessário converte-la para SHA1 (utilizando Byte Array), com este resultado realizar a conversão para BASE64. Tendo em vista que a conversão para BASE64 irá trazer caracteres incoerentes para passagem da URL, será necessário fazer a conversão para URL-ENCODE.

  • Senha: testPassword
  • BASE64(SHA1): i7YRj4/Wk1rQh2o740pxfTJwj/0=
  • URL-ENCODE: i7YRj4%2FWk1rQh2o740pxfTJwj%2F0%3D

Observe que por trazer os caracteres " / e = " na conversão de SHA1 e BASE64, é necessário o URL-ENCODE.

Sugestão para URL-ENCODE: https://meyerweb.com/eric/tools/dencoder/


Bloco de código
languageruby
themeEclipse
titleExemplo de Conversão
linenumberstrue
DEFINE VARIABLE testPass AS CHARACTER NO-UNDO.
testPass = BASE64-ENCODE(SHA1-DIGEST(LC("testPassword"))).                 
// Utilize uma lógica de conversão URL-ENCODE para variavel testPass

draw.io Diagram
bordertrue
viewerToolbartrue
fitWindowfalse
diagramNameencode
simpleViewerfalse
diagramWidth591
revision2

Aviso
titleAviso importante!

Para realizar esse encode NÃO pode utilizar codificação HEXADECIMAL, caso que acontece no Java (processo interno da linguagem), então é preciso utilizar o Byte Array!

Dica
titleExemplo de URL final

http://localhost:8180/dts/datasul-rest/resources/login?username=teste&password=i7YRj4%2FWk1rQh2o740pxfTJwj%2F0%3D



Expandir
titleNova arquitetura DTS4THF (TOMCAT)


draw.io Diagram
bordertrue
viewerToolbartrue
fitWindowfalse
diagramNameBASIC
simpleViewerfalse
diagramWidth502
revision2