Histórico da Página
Informações | ||
---|---|---|
| ||
|
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 | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
| ||||||||||
|
Esta funcionalidade está disponível para utilização conforme apresentado no quadro abaixo:
Formato URL
O Guia de Implementação de API TOTVS define que o formato das URIs dos endpoints devem conter o nome do produto, o módulo, a versão da API e o recurso alvo da
funcionalidade em questão.
Contextos:
- /prg
Tomando como exemplo o endpoint de integração do recurso de "Usuários" do módulo de "Foundation" do produto "Datasul", a URI básica deste serviço deve ser: /prg/fnd/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:
Informações | ||
---|---|---|
| ||
http://host:port/dts/datasul-rest/resources/prg/fnd/v1/users |
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. |
- /api
Para exemplo do funcionamento /api vamos utilizar o mesmo recurso de integração de usuário exemplificado anteriormente: a URI deste serviço deve ser: /api/fnd/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/
Informações | ||
---|---|---|
| ||
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
Para "publicar" a funcionalidade Progress ABL basta criar o programa (.p) com o seguinte caminho: fnd/api/v1/users.p (<módulo>/api/<versão API>/<recurso>.p). A sub-pasta "api" passa então a concentrar todas as funcionalidades de integração do módulo em questão. Outros caminhos e parâmetros podem ser adicionados a URL, mas sempre de acordo com o Guia de Implementação de APIs.
Aviso |
---|
Os programas Progress disponibilizados, deverão seguir o padrão de localização abaixo: <módulo>/api/<versão API>/<recurso>.p |
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 deve ser feita 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 através das 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:
Bloco de código |
---|
{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:
{utp/ut-api.i}
É a include principal, que possui os parâmetros de entrada e saída do serviço API, nesta include é feito a inicialização das funções utilitárias.
{utp/ut-api-action.i pi-send GET /~*/SEND by=email,address=~* }
Neste exemplo, está sendo definido uma rota, sendo que toda requisição de método GET, que contenha os filtros informados, será direcionado a procedure pi-send.
/~*/SEND by=email,address=~*
Em relação ao filtro informado, será capturado todas as requisições que possuírem um parâmetro Path "SEND", um parâmetro Query "by" com conteúdo "email" e um parâmetro Query "address" com qualquer conteúdo (*).
{utp/ut-api-action.i pi-update POST /~* }
No exemplo acima, está sendo definida uma rota, no qual toda requisição de método POST, será direcionada para a procedure pi-update.
{utp/ut-api-action.i pi-find GET /~* }
Neste exemplo, todas as requisições de método GET, que possuirem parâmetros (Query ou Path) informados, será direcionado para a procedure pi-find.
{utp/ut-api-action.i pi-default GET }
No exemplo acima, para requisições de método GET, que não encontrarem nenhuma rota compatível, será direcionada para a procedure pi-default.
{utp/ut-api-notfound.i}
Caso nenhuma procedure interna tenha sido encontra retorna uma mensagem "Method not found" com HTTP Status 400.
Informações |
---|
Algumas considerações sobre o uso da include de roteamento (ut-api-action):
|
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. |
Formato Mensagem JSON
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. Através desta mensagem, o desenvolvedor poderá efetuar os devidos filtros e classes utilitárias necessárias.
Exemplo de mensagem:
Bloco de código | ||
---|---|---|
| ||
{ uri: valor, method: GET, headers: {}, pathParams: [ "param1", "param2" ], queryParams: { query1: [valor1, valor2], query2: [valor1]}, payload: { }, multyPartFile: [ {file: ...}, {file: ...}] } |
Classes utilitárias
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
Login
Para realizar o login no DATASUL-REST é necessário passar como parâmetro usuário e senha na seguinte URL.
Dica | ||
---|---|---|
| ||
http://localhost:8180/dts/datasul-rest/resources/login?username=USER&password=PASSWORD |
Para passagem da senha é necessário converte-la para SHA1, 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.
Bloco de código | ||||
---|---|---|---|---|
| ||||
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 |
Dica | ||
---|---|---|
| ||
http://localhost:8180/dts/datasul-rest/resources/login?username=super&password=i7YRj4%2FWk1rQh2o740pxfTJwj%2F0%3D |