API demo para desenvolvimento do exemplo
Neste exemplo, será mostrado o envio de dados no formato JSON para serem consumidos por uma API criada especificamente para este propósito.
...
O arquivo executável será postado abaixo:
View file | ||
---|---|---|
|
Desenvolvendo o Script
O Script foi feito para ser utilizado em qualquer evento, de qualquer tabela, com o VsScripter, podendo ser executado ali mesmo diretamente do editor de scripts para efeitos didáticos.
Abaixo, segue o código a ser copiado/digitado no editor VsScripter:
Code Block | ||
---|---|---|
| ||
uses // units necessárias para o projeto. Todas são de inclusão manual uVsHttpRequest, uLkJson, Classes; const // constantes necessárias para o Login que baixará o token de autenticação User = 'admin'; Password = 'admin'; var // variáveis globais necessárias para efetivar os "requests http", de armazenamento // do token, de criação de um objeto JSON e do armazenamento do resultado (Response) // sequencialmente http : TVsHttp; cUrl : String; |
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
...
|
...
|
...
|
...
|
...
|
...
token |
...
: |
...
String; |
...
|
...
|
...
|
...
jsonO |
...
: TlkJSONobject; resultado: THttpResponse; dados: TStringList; |
...
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
// criando uma função para tratar os erros |
...
mais |
...
comuns |
...
nos |
...
"requests |
...
http" |
...
function RetornaErro(erro: Integer):String; begin case erro |
...
of |
...
400: Result := IntToStr(erro)+' - |
...
Requisição |
...
ruim: |
...
A |
...
requisição |
...
não |
...
pôde |
...
ser '+ ' |
...
interpretada |
...
pelo |
...
servidor |
...
em razão de erros de formato/sintaxe.'; 401: Result := IntToStr(erro)+' - Não autorizado:'#13#13'A requisição requer '+ |
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
'autenticação por parte do cliente e as informações de '+ ' |
...
autenticação não foram localizadas ou não são válidas.'; 403: Result := IntToStr(erro)+' - Indica que o servidor entendeu |
...
o pedido, '+ ' |
...
mas |
...
se |
...
recusa |
...
a autorizá-lo. Esse status é semelhante ao 401, '+ |
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
'mas neste caso, a re-autenticação não fará diferença.'; 404: Result := IntToStr(erro)+' |
...
- A página não |
...
foi |
...
encontrada |
...
ou |
...
não |
...
existe |
...
'+ |
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
'mais. |
...
'#13#13' |
...
Entre as principais causas para aparecer o '+ ' |
...
problema |
...
estão: |
...
páginas |
...
removidas |
...
do |
...
site, |
...
modificação |
...
na |
...
'+
' |
...
URL sem um redirecionamento e erros de digitação no navegador.'; |
...
405: Result := IntToStr(erro)+' - |
...
Método |
...
não permitido:'#13#13'O método HTTP '+ ' |
...
utilizado |
...
não |
...
é |
...
permitido |
...
para |
...
o |
...
recurso |
...
identificado |
...
na URL.'; 422: Result := IntToStr(erro)+' - Entidade não |
...
processável:'#13#13'O servidor '+ 'reconhece que as informações estão na sintaxe correta, mas ' |
...
+ |
...
'seu conteúdo está semanticamente incorreto.'; 500: Result := IntToStr(erro)+' |
...
- Indica problemas com a |
...
estrutura do site '+ |
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
'que o usuário deseja acessar, |
...
então |
...
não |
...
se |
...
trata |
...
de um bug '+ |
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
'com |
...
o |
...
computador |
...
ou |
...
navegador, |
...
nem |
...
mesmo |
...
com a Internet do '+ 'usuário.'; 11001: Result := IntToStr(erro)+'Sem conexão com a Internet' else // caso o número do erro não esteja listado acima, será mostrado seu número // sem a devida descrição. Result := 'Erro retornado: '+IntToStr(erro); end; end; // Procedure para buscar o token de autenticação |
...
necessário para consumo |
...
da API Procedure PegaToken; |
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
begin // cria um objeto chamado http, do tipo TVsHttp, responsável pelos "requests" // |
...
http da |
...
API |
...
consumida |
...
|
...
|
...
http |
...
:= TVsHttp.Create; try // informa |
...
ao método "POST" da requisição http que o conteúdo enviado é do // |
...
tipo |
...
JSON |
...
|
...
|
...
|
...
|
...
http.ContentType := 'application/json'; |
...
// |
...
URL |
...
da |
...
API |
...
a ser |
...
consumida |
...
|
...
|
...
|
...
|
...
cUrl := 'http://127.0.0.1:2001/tms/auth/LoginService/Login'; |
...
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
// |
...
envio da requisição http, por meio do |
...
método |
...
"POST", |
...
para |
...
solicitar |
...
o |
...
// |
...
novo |
...
token |
...
de |
...
autenticação. |
...
As |
...
API's |
...
possuem |
...
tempos |
...
de validade do token |
...
// |
...
diferenciados. |
...
Cada |
...
provedor |
...
de |
...
serviços |
...
web |
...
saberá |
...
dizer |
...
de |
...
quanto |
...
em |
...
|
...
|
...
|
...
// |
...
quanto |
...
tempo |
...
o |
...
token |
...
deve |
...
ser |
...
renovado. |
...
Neste |
...
exemplo, |
...
ele |
...
sempre |
...
será |
...
// |
...
renovado |
...
no momento de sua execução, por meio desta "Procedure". // resultado é um objeto do tipo THttpResponse, que receberá toda a resposta // oriunda da requisição enviada por meio |
...
do objeto http. // |
...
cUrl |
...
é |
...
a |
...
URL |
...
da |
...
API |
...
definida |
...
acima. |
...
User |
...
e |
...
Password |
...
são |
...
os |
...
parâmetros // |
...
necessários |
...
ao |
...
Login |
...
dessa |
...
"Procedure" na API para baixar o |
...
token. |
...
|
...
resultado |
...
:= http.Post(cUrl, Format('{"User":"%s","Password":"%s"}', |
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
[User, Password])); // |
...
verificando |
...
se o resultado |
...
recebido é um erro ou se deu certo o envio dos // |
...
dados |
...
por |
...
meio |
...
da propriedade |
...
resultado.StatusCode. |
...
Se |
...
o |
...
valor de StatusCode // for igual ou maior que 400, indica que houve um erro e ele será tratado pela // função RetornaErro. |
...
// caso o valor de StatusCode seja 200, isso indica que houve sucesso na requi- // sição http |
...
e |
...
o resultado será transformado em um objeto JSON para, aí, ser // atribuído a variável token. if resultado.StatusCode >= 400 then ShowMessage('Pega token: '+RetornaErro(resultado.StatusCode)) else if resultado.Statuscode = 200 then begin jsonO := TlkJSON.ParseText(resultado.Response) as TlkJSONObject; token := jsonO.Field['value'].value; end; |
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
finally // |
...
finaliza |
...
os |
...
dois |
...
objetos para |
...
liberar memória. http.Free; |
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
jsonO.Free; |
...
end; end; // |
...
criando |
...
a |
...
função |
...
EnviaDados |
...
Function EnviaDados(cDados: TStringList; geraToken: Boolean):THttpResponse; var // declarando o objeto obj para preparação do cabeçalho http obj |
...
: |
...
TCustomHeader |
...
; begin try |
...
// |
...
se |
...
foi |
...
passado |
...
true |
...
para |
...
o |
...
parâmetro |
...
geraToken, |
...
será |
...
gerado |
...
um novo token |
...
|
...
if |
...
geraToken |
...
then |
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
PegaToken; // cria parâmetro do Head http chamado Authorization |
...
e |
...
envia |
...
o |
...
token |
...
para |
...
|
...
|
...
|
...
|
...
// |
...
autenticação para consumo da API |
...
|
...
|
...
|
...
|
...
obj := TCustomHeader.Create('Authorization', 'Bearer ' + token); // |
...
cria um objeto chamado http, |
...
do |
...
tipo |
...
TVsHttp, |
...
responsável |
...
pelos |
...
"requests" |
...
|
...
|
...
// http da |
...
API |
...
consumida |
...
http := TVsHttp.Create; |
...
|
...
|
...
|
...
|
...
|
...
// informa ao |
...
método "POST" |
...
da requisição http que o conteúdo enviado é do // tipo JSON http.ContentType |
...
:= 'application/json'; |
...
|
...
|
...
|
...
|
...
// |
...
adiciona |
...
autenticação |
...
criada |
...
no |
...
objeto |
...
obj |
...
ao cabeçalho customizado |
...
no // |
...
objeto |
...
http |
...
|
...
|
...
|
...
|
...
|
...
http.CustomHeaders.Add(obj); // URL |
...
da |
...
API a |
...
ser |
...
consumida |
...
|
...
|
...
|
...
cUrl |
...
:= |
...
'http://127.0.0.1:2001/tms/xdata/apiservice/enviarpedido'; // Result retorna o resultado vindo |
...
da |
...
API |
...
consumida. |
...
Se |
...
os dados |
...
|
...
foram |
...
|
...
|
...
|
...
|
...
// recebidos e processados, |
...
ou se houve erro e qual é o erro. Result := |
...
http. |
...
Post(cUrl, cDados.Text); finally |
...
// destrói o objeto http |
...
http.free; end; end; |
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
// |
...
execução |
...
do |
...
Script |
...
begin |
...
|
...
// cria objeto dados do |
...
tipo TStringList, que receberá os dados a serem en- // viados para a |
...
API, |
...
como |
...
"Body" |
...
da |
...
requisição |
...
http. |
...
|
...
|
...
|
...
dados |
...
:= TStringList.Create(); // início do ciclo de vida do script try // |
...
adiciona dados |
...
a |
...
TStringList |
...
dados, que |
...
serão enviados à função EnviaDados dados.Add('{'); dados.Add('"PedidoId":1,'); dados.Add('"ClienteID":"000456",'); dados.Add('"ClienteNome":"000456",'); dados.Add('"ProdutoID":"164756392300",'); dados.Add('"ProdutoQTD":100,'); dados.Add('"ProdutoValorUnt":12.5'); dados.Add('}'); // |
...
recebe o |
...
resultado |
...
vindo |
...
função |
...
EnviaDados, |
...
por |
...
meio |
...
de |
...
'http |
...
response' |
...
|
...
resultado |
...
:= EnviaDados(dados, true); // |
...
verificando |
...
se o |
...
resultado recebido |
...
é |
...
um |
...
erro |
...
ou |
...
se |
...
deu |
...
certo o envio dos // |
...
dados |
...
por |
...
meio da propriedade resultado.StatusCode. Se o valor de StatusCode |
...
|
...
// for igual ou maior que 400, indica que houve um erro e ele será tratado pela |
...
// |
...
função |
...
RetornaErro. |
...
...
|
...
|
...
|
...
// caso o valor de StatusCode seja 200, isso indica que houve sucesso na requi- // sição http e o resultado retornado |
...
será mostrato por meio do ShowMessage // |
...
que é exatamente o retorno da API que está programada para retornar o |
...
// |
...
mesmo |
...
JSON enviado. if resultado.StatusCode >= 400 then ShowMessage('Envio de dados: ' + RetornaErro(resultado.StatusCode)) else if resultado.Statuscode = 200 then ShowMessage('HTTP 200 OK'#13#13+ 'Esses foram os dados enviados:'#13#13 +resultado.Response); finally // destrói a TStringList dados para liberar memória. dados.free; end; end; |