Consumo de uma API, com recebimento de dados no formato JSON, dentro de um Projeto Personalizado do VsScripter
Objetivo
O objetivo deste documento é auxiliar o usuário a criar um “script” para consumo de API Rest, que fornece dados de cotação de moeda, gravando-os em uma tabela personalizada, chamada “U_COTACAOMOEDAS”.
Criando a tabela personalizada “U_COTACAOMOEDAS”
Será necessário utilizar o Person para criar a tabela “U_COTACAOMOEDAS”. Caso exista alguma dúvida sobre o funcionamento do Person, a documentação a seguir deverá ser consultada. https://nimitz.atlassian.net/wiki/spaces/TD/pages/1991213070
Estrutura da tabela
Abaixo é descrita a estrutura da tabela personalizada, a qual receberá os dados da cotação
Nome da tabela: U_COTACAOMOEDAS
Descrição: Tabela para cotação cotação de moedas
Coluna | MOEDABASE |
Descrição completa/reduzida | Moeda Base |
Dica para usuário | Moeda a ser convertida |
Tipo da coluna | Texto |
Tamanho máximo | 10 caracteres |
|
|
Coluna | MOEDADESEJADA |
Descrição completa/reduzida | Moeda desejada |
Dica para usuário | Moeda desejada para o cálculo da moeda base |
Tipo da coluna | Texto |
Tamanho máximo | 10 caracteres |
|
|
Coluna | NOMECONVERSAO |
Descrição completa/reduzida | Descrição |
Dica para usuário | Descrição da conversão |
Tipo da coluna | Texto |
Tamanho máximo | 50 caracteres |
|
|
Coluna | VALORMAXIMO |
Descrição completa/reduzida | Valor máximo |
Dica para usuário | Valor máximo da moeda na data |
Tipo da coluna | Número |
Quantidade casas inteiras / decimal | 4 / 4 |
|
|
Coluna | VALORMINIMO |
Descrição completa/reduzida | Valor mínimo |
Dica para usuário | Valor mínimo da moeda na data |
Tipo da coluna | Número |
Quantidade casas inteiras / decimal | 4 / 4 |
|
|
Coluna | PCTVARIACAO |
Descrição completa/reduzida | Porcentagem de Variação / Variação |
Dica para usuário | Porcentagem de Variação |
Tipo da coluna | Número |
Quantidade casas inteiras / decimal | 3 / 4 |
|
|
Coluna | PRECOCOMPRA |
Descrição completa/reduzida | Preço de compra |
Dica para usuário | Preço pago na compra da moeda |
Tipo da coluna | Número |
Quantidade casas inteiras / decimal | 4 / 4 |
|
|
Coluna | PRECOVENDA |
Descrição completa/reduzida | Preço de venda |
Dica para usuário | Preço de venda da moeda |
Tipo da coluna | Número |
Quantidade casas inteiras / decimal | 4 / 4 |
|
|
Coluna | VARIACAO |
Descrição completa/reduzida | Variação |
Dica para usuário | Valor da variação de preços |
Tipo da coluna | Número |
Quantidade casas inteiras / decimal | 4 / 4 |
|
|
Coluna | DATACOTACAO |
Descrição completa/reduzida | Data da cotação |
Dica para usuário | Data na qual a cotação foi feita |
Tipo da coluna | Data e hora |
Após criação da tabela, a mesma deverá ficar parecida com a figura abaixo:
Criando o “script” por meio do Gerenciador de Projetos
Para iniciar o editor do VsScripter, no Gerenciador de Projetos, clique no botão Novo Projeto. O nome do projeto será solicitado, conforme imagem abaixo:
Utilize o nome “CotacaoMoedas” para o projeto e clique no botão OK.
Inicialmente, a tela de edição do VsScripter será mostrada apenas com a “unit” uPrinc, conforme abaixo:
Entendendo o código do “script”
Copie ou digite o código abaixo na “unit” uPrinc:
uses
// dá acesso ao conteúdo "unit" uPesquisaCotacao
uPesquisaCotacao;
var
// reserva espaço na memória para um objeto com o nome form que
// herdará todas as características do formulário TfrmPesquisaCotacao
form : TfrmPesquisaCotacao;
begin
// início do ciclo de vida do "script"
try
// cria, efetivamente, um objeto com o nome form que herdará todas as
// características do formulário TfrmPesquisaCotacao
form := TfrmPesquisaCotacao.Create(nil);
// monitora o status do objeto "form". Assim, quando as operações
// finalizarem e o ModalResult do formulário for mrOk, o ciclo de vida
// do "script" será finalizado. Qualquer ação que seja pretendida após o
// final do "script", como mensagens ao operador, devem ser colocadas
// entre o begin e o end logo abaixo
if form.ShowModal = mrOk then
begin
end;
// final do ciclo de vida do "script"
finally
// libera o objeto "form" da memória, destruindo todos os dados e objetos
// criados nele.
form.Free;
end;
end;
Criando o formulário “frmPesquisaCotacao”
Para criar um novo formulário, acessar o menu “File” e em seguida o submenu “New Form”, ou clicando no botão “New form”, que é representado por um formulário em branco com uma estrela amarela na parte superior esquerda.
O novo formulário precisará de dois componentes, listados abaixo:
Componente | Novo nome (Name) | Caption / Text |
TButton | btnProcessar | &Pesquisar |
TComboBox | cboEscolherCotacao | Escolha a conversão desejada |
Os componentes visuais ficam na “Tool Palette”, a direita. Selecionar um componente por vez, clicando, segurando o botão do mouse e arrastando o componente para o formulário. Assim, repetir para todos os componentes.
As propriedades “Name”, “Caption” e “Text” são propriedades que podem ser alteradas na barra a esquerda, chamada “Object Inspector. Essas alterações devem ser feitas uma por uma, em cada componente. Ou seja, selecionar um componente e alterar suas propriedades “Name”, “Caption” e “Text”, um componente por vez.
A propriedade “Caption” pertence ao componente “TButton”. No caso do componente “TComboBox”, a propriedade “Text” é que deve ser mudada.
Além disso, os itens do “TComboBox”, na propriedade “Items” são: USD-BRL, EUR-BRL, USD-BRLT e BTC-BRL. Eles devem ser digitados um por linha, ou seja, pressionando o Enter ao final de cada um e não deve ser colocado vírgula após cada item.
O “layout” do formulário deve ficar parecido com o abaixo, embora o usuário seja livre para fazer da sua maneira:
Para salvar os trabalhos feitos até agora, pressionar o ícone que presenta dois “disquetes” pretos ou a combinação “CTRL+SHIFT+S”.
O novo formulário “frmPesquisaCotacao” é a parte gráfica do projeto do “script”. Quando for solicitado um nome de sua “unit”, que é a parte dos códigos do “script” em si, salvar com o nome “uPesquisaCotacao”.
Com a tecla “F12” é possível mudar entre os modos de “Design” (“layout” gráfico e colocação de componentes) e “Code” que é parte e programação.
Pressionar “F12” para mudar para o modo de programação do “script”. O código abaixo deve ser copiado/digitado na área de programação:
Código da “unit” uPesquisaCotacao:
{$FORM TfrmPesquisaCotacao, uPesquisaCotacao.sfm}
uses
Classes, Graphics, Controls, Forms, Dialogs, Db, DbClient;
uses
uVsHttpRequest, IdSSLOpenSSL, uLkJson, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, VsMask, System;
var
http: TVsHttp;
SSL1 : TIdSSLIOHandlerSocketOpenSSL;
cUrl : String;
obj : TlkJSONobject;
Function buscarMoedas(moedas: String):String;
begin
http := TVsHttp.Create;
cUrl := Format('https://economia.awesomeapi.com.br/%s', [moedas]);
//somente necessário para https
SSL1 := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
IdSSLOpenSSL.UnLoadOpenSSLLibrary();
try
//essas opções vai de cada servidor
SSL1.SSLOptions.Method := sslvTLSv1_2;
SSL1.SSLOptions.SSLVersions := [sslvTLSv1_2];//, sslvTLSv1, sslvSSLv23, sslvTLSv1_1, sslvTLSv1_2];
//associando o SSL ao componente de conexão
http.SetIOHandler(SSL1);
//primeira consulta get simples
Result := http.get(cUrl);
// Se precisar analisar o retorno, remover comentário do comando abaixo
// showMessage(Result);
finally
SSL1.free;
http.free;
end;
end;
function trocaPonto(valor: String):String
var
x: Integer;
nStr: String;
begin
nStr := '';
for x:=1 to length(valor) do
begin
if copy(valor, x, 1) <> '.' then
nStr := nStr + copy(valor, x, 1)
else
nStr := nStr + ',';
end;
Result := nStr;
end;
function GravaCotacao(jsonO: TlkJSONobject):Boolean;
var
cdsMoeda: TClientDataSet;
begin
try
// cria o objeto cdsMoeda do tipo TClientDataSet
cdsMoeda := TClientDataSet.Create(nil);
// preparando o objeto cdsMoeda para receber um TDataSetProvider com nome formado por
// dsp+NOMETABELA e abertura automática
dmConexao3c.GetDspEdicao(cdsMoeda, 'U_COTACAOMOEDAS', true);
// abre o cdsMoeda
cdsMoeda.open;
// coloca o cdsMoeda em modo de inserção de dados
cdsMoeda.Append;
// busca um valor válido e ordenado que será o índice da tabela, armazenado em
// U_COTACAOMOEDAS_ID
cdsMoeda.FieldByName('U_COTACAOMOEDAS_ID').value :=
dmConexao3c.QueryPegaCampo('SEL_PADRAO_COM_WHERE',
'MAX(U_COTACAOMOEDAS_ID)',
['?', '1:s', 'U_COTACAOMOEDAS',
'?', '2:s', '0=0'],
[ftString, ftString],
[20, 100])+1;
// atribui ao campo MOEDABASE o valor da chave code
cdsMoeda.FieldByName('MOEDABASE').value := jsonO.Field['code'].value;
// atribui ao campo MOEDADESEJADA o valor da chave codein
cdsMoeda.FieldByName('MOEDADESEJADA').value := jsonO.Field['codein'].value;
// atribui ao campo NOMECOVERSAO o valor da chave name
cdsMoeda.FieldByName('NOMECONVERSAO').value := jsonO.Field['name'].value;
// atribui ao campo VALORMAXIMO o valor da chave high
cdsMoeda.FieldByName('VALORMAXIMO').value :=
trocaPonto(jsonO.Field['high'].value);
// atribui ao campo VALORMINIMO o valor da chave low
cdsMoeda.FieldByName('VALORMINIMO').value :=
trocaPonto(jsonO.Field['low'].value);
// atribui ao campo PCTVARIACAO o valor da chave pctChange
cdsMoeda.FieldByName('PCTVARIACAO').value :=
trocaPonto(jsonO.Field['pctChange'].value);
// atribui ao campo PRECOCOMPRA o valor da chave bid
cdsMoeda.FieldByName('PRECOCOMPRA').value :=
trocaPonto(jsonO.Field['bid'].value);
// atribui ao campo PRECOVENDA o valor da chave ask
cdsMoeda.FieldByName('PRECOVENDA').value :=
trocaPonto(jsonO.Field['ask'].value);
// atribui ao campo VARIACAO o valor da chave varBid
cdsMoeda.FieldByName('VARIACAO').value :=
trocaPonto(jsonO.Field['varBid'].value);
// atribui ao campo DATACOTACAO o valor da chave create_date
cdsMoeda.FieldByName('DATACOTACAO').Value :=
DateTimeToStr(jsonO.Field['create_date'].Value);
// Indica ao cds que os dados podem ser gravados
cdsMoeda.post;
// indica ao servidor de aplicações para aplicar as alterações feitas
dmConexao3c.CDSApplyUpdates([cdsMoeda]);
finally
// destruindo os objetos em memória
cdsMoeda.free;
showMessage(Format('Cotação: %s'+#13#13+
'Valor mínimo: R$ %s'+#13#13+
'Valor máximo: R$ %s'+#13#13+
'Data: %s',
[jsonO.Field['name'].value,
trocaPonto(jsonO.Field['bid'].value),
trocaPonto(jsonO.Field['ask'].value),
DateTimeToStr(jsonO.Field['create_date'].Value)]));
end;
end;
procedure btnPesquisarClick(Sender: TObject);
var
obj : TlkJSONobject;
json : WideString;
jsonL : TlkJSONlist;
jsonO : TlkJSONobject;
i : Integer;
cdsMoeda: TClientDataSet;
begin
try
// recebe o json relativo à conversão das moedas.
json := UTF8Encode((buscarMoedas(cboEscolherCotacao.Items[cboEscolherCotacao.ItemIndex])));
// se json não estiver vazio e não conter '#erro' em seu conteúdo.
if ((Length(json) > 0) and (Pos('#erro', lowercase(json)) = 0)) then
begin
// transforma o conteúdo de json em uma lista JSON
jsonL := TlkJSON.ParseText(Json) as TlkJSONlist;
// verifica se a lista foi criada com sucesso
if assigned(jsonL) then
begin
// cria um 'loop' para processar todos os itens da lista Json
for i:=0 to jsonL.count-1 do
begin
// cria um objeto json, equivalente a um registro
jsonO := jsonL.child[i] as TlkJSONobject;
GravaCotacao(jsonO);
end;
end else
// se a lista JSON não for criada
ShowMessage('Não carregou a conversão de moedas.');
end else
// se existir alguma mensagem de erro, ela é mostrada ao usuário
if Pos('#erro', lowercase(json)) > 0 then
ShowMessage(Format('Erro retornado: %s', [UTF8Encode(json)]));
finally
// finaliza os objetos criados e retorna a constante mrOk para indicar que o
// processo finalizou.
jsonL.Free;
ModalResult := mrOk;
end;
end;
Salvar novamente o projeto do “VsScripter” e fechar seu editor.
Testando o “script” de cotação de moedas
Para testar o “script”, é necessário executá-lo por meio do botão Executar, a partir do Gerenciador de Projetos:
Após efetuar a troca do usuário, o projeto Cotação de Moedas aparecerá no menu Projetos Personalizados, conforme imagem abaixo:
Escolher uma das cotações disponíveis, por meio do campo “Escolha a conversão desejada” e pressionar o botão “Pesquisar”. Em alguns segundos, será mostrado o nome da cotação, os valores mínimo e máximo e a data da cotação, além desses dados serem gravados automaticamente na tabela U_COTACAOMOEDAS, conforme figura abaixo: