20 de maio de 2020 - Frederico Marinho

REST/JSON com Lazarus (Delphi) – Passo-a-passo da instalação em Windows

Num passado não muito recente tive um desafio enorme de integrar uma loja virtual que implementei para um cliente em Prestashop com um sistema legado, que faz toda a gestão da empresa com mais de 35 mil produtos, criado em Visual Basic e utilizando Access como banco de dados. Arrepio até hoje lembrando o que passei, rsrs. O sistema já não tinha mais manutenção há muitos anos, fazer alterações no código original seria um risco que preferi não arriscar. Não queria atrapalhar o funcionamento do processo atual da empresa. Pra mim era melhor ter um delay de atualização e correr o risco de vender online produtos sem estoque, do que atrapalhar o funcionamento da loja física, com seus 5 caixas que trabalhavam incessantemente. Por isso também descartei a ideia de colocar o banco online e fazer a integração a partir do Prestashop.

Logo cheguei na conclusão que ter um sistema intermediário, para interligar o gestor com a loja virtual seria a melhor opção (mesmo sabendo que ia perder a possibilidade de atualização on-time). Decidi então utilizar uma linguagem que já tinha estudado bastante mas que há muito não utilizava porém seria mais fácil e rápido do que estudar algo novo, principalmente por causa da conexão com Access que me assustava. E ainda tinha outro problema, não podia manter uma conexão ativa no banco, porque Access tem restrições de conexões simultâneas. Decidi então criar um software em Delphi, que lê facilmente qualquer base de dados MDB, exportar as atualizações para um arquivo TXT  e enviar esse TXT para a loja virtual. Ufa.

Mas Delphi não é gratuito, não tenho o Delphi original. Parti então para o desenvolvimento utilizando Lazarus, free e open-source, a opção mais lógica.

Bom, a questão da criação desse post é que preparar o ambiente é meio complicado. Talvez porque não utilizo Lázarus ou Delphi no dia-a-dia, então esse texto visa ajudar a quem precise dessa solução pontualmente, para resolver um problema específico. Não pretendo aprofundar muito nos conceitos de REST ou mesmo na linguagem Pascal e, principalmente, a ideia desse post é me ajudar também quando precisar fazer algo parecido novamente. Passei um aperto danado para chegar no resultado final, mas deu certo! rsrs

Instalação do Lazarus

A primeira coisa, óbvio, fazer download e instalar o Lazarus de acordo com o seu sistema operacional. Faça o download aqui: https://www.lazarus-ide.org/index.php?page=downloads

A instalação geralmente demora um pouquinho, mas é bem simples, no estilo next-next-done.


Instalação do Indy

Componente para comunicações cliente/servidor

Indy é uma biblioteca de comunicação cliente/servidor de código aberto que suporta sockets TCP/UDP/RAW e mais de 100 protocolos como HTTP, SMTP, POP3, IMAP, FTP, etc. Vamos precisar baixar uma versão desenvolvida especificamente para o Lazarus, que atualmente está na versão 10.

A instalação é um pouco burocrática e encontrei os passos aqui http://wiki.freepascal.org/Indy_with_Lazarus#How_to_install_.5B2.5D mas vou detalhar pra facilitar:

  1. Faça o download do componente aqui: https://github.com/IndySockets/Indy

Houve uma atualização recente no GitHub e a versão atual do repositório parece não estar funcionando muito bem. Tenho a versão anterior no meu servidor que você pode baixar aqui, essa compilando perfeitamente. Se você conseguiu compilar a versão do GitHub deixe nos comentários por favor, daí consigo atualizar também minha versão local.

  1. Descompacte o arquivo em uma pasta com o nome que achar mellhor.
  2. Abra o Lazarus. Se você estiver abrindo-o pela primeira vez, será preciso clicar em Iniciar IDE.
  3. Acesse o menu: Pacote -> Abrir Arquivo de Pacote (.lpk) e abra o arquivo indylaz.lpk dentro da pasta Lib (que está dentro da pasta descompactada).

  1. Ao abrir a tela acima, clique em Compilar duas vezes. Depois acesse Usar -> Instalar. Você será perguntado se o Lazarus pode ser reconstruído. Clique em Sim, ele será reiniciado.
    1. Devido a um bug desconhecido no FPC, você precisa compilar o pacote Indy duas vezes antes de instalar.

Nesse ponto o processo está basicamente pronto. Com o Indy instalado você já está apto a conectar em um servidor REST/Json.

Os próximos passos são opcionais mas auxiliam em outros procedimentos que na maioria das vezes são bastante úteis como um XML parser para trabalhar com arquivos XML; um URL enconder para codificar URLs e o OpenSSL no caso de precisar acessar uma URL com a camada SSL, ou seja, HTTPS.


Instalar o XML Parser

O interpretador XML é bastante útil se você vai consumir algum servidor REST que retorne ou receba XML. Pode acontecer. Prestashop por exemplo só trabalha com XML em alguns métodos, então precisei utilizar.

  1. Faça download do xmlparser-1.0.20.zip (se você encontrar uma versão atualizada e funcionar bem, deixa o link nos comentários pra gente).
  2. Descompacte o arquivo aonde você preferir.
  3. No Lazarus, acesse o menu Pacote -> Abrir Arquivo de Pacote (.lpk) e abra o arquivo xmlparserpack.lpk.

  1. Compile também duas vezes e depois acesse Usar -> Instalar.

No final do processo o Lazarus será reiniciado.


Instalar o URL Encode

Um componente para codificar e decodificar URLs. Bastante útil quando é preciso concatenar strings na URL.

  1. Faça o download da versão estável aqui: http://www.ararat.cz/synapse/lib/exe/fetch.php/file:synapse40.zip
  2. Descompacte o arquivo aonde você preferir.
  3. No Lazarus, acesse o menu Pacote -> Abrir Arquivo de Pacote (.lpk) e abra o arquivo laz_synapse.lpk na pasta synapse40/source/lib.

  1. Selecione todos os arquivos .pas (utilizando a tecla Ctrl) e clique em Usar -> Adicionar ao Projeto.

Exemplo de uso:

uses
 SynaCode;
 ..
 begin
 s := EncodeUrl( str );

s := DecodeUrl( str );
 end;

Instalar OpenSSL

Ao tentar conectar em uma URL com HTTPS você pode receber o erro Could Not Load SSL Library.

Para solucionar o erro é necessário baixar as DLL’s libeay32.dall e ssleay32.dll através dos links abaixo.

Após realizar o download você deve inserir as DLLs no diretório:

  • C:\Windows\System32 (para Windows 32 bits)
  • C:\Windows\SysWOW64 (para Windows 64 bits)
  • Ou, caso a aplicação já esteja compilada, pode também colocar os arquivos DLLs na pasta do executável.

Feito isso o erro não voltará a acontecer.


Erro: ssl routines:ssl3_read_bytes:tlsv1 alert protocol version

Atualização: 24/01/2022

Recentemente, ao atualizar o servidor de um dos clientes, comecei a receber a mensagem de erro:

ssl routines:ssl3_read_bytes:tlsv1 alert protocol version

Fácil identificar o problema: o servidor estava com uma versão atualizada do SSL, enquanto o app Lazarus estava numa versão anterior.

Achei a solução aqui e graças a Deus foi fácil de resolver. Vamos lá:

  • Declare a variável responsável por controlar o protocolo SSL utilizado.
SSL_org: TIdSSLIOHandlerSocketOpenSSL;
  • Agora, imediatamente antes de criar o componente httpClient, provavelmente uma linha parecida com essa:
httpClient := TIdHttp.Create(nil);
  • Crie o componente HandlerSocket e informe as versão SSL utilizadas:
SSL_org := TIdSSLIOHandlerSocketOpenSSL.Create();
SSL_org.SSLOPtions.SSLVersions := [sslvTLSv1, sslvTLSv1_1, sslvTLSv1_2];
  • Agora é só associar o componente HandlerSocket ao httpClient, logo após a linha de crição:
httpClient := TIdHttp.Create(nil);
httpClient.IOHandler := SSL_org;

Pronto! Agora é só correr para o abraço!

3

Desenvolvimento web / Webservice/API

Comments

  • Raphael disse:

    Olá
    Obrigado por compartilhar estou analisando a possibilidade de utilizar o Lazarus para desenvolver uma dll para um projeto de um cliente. Sou programador DotNet.
    Consegui compilar a versão atual sem nenhum problema.

  • Eduardo disse:

    Frederico, eu consegui, usei um componente TIdSSLIOHandlerSocketOpenSSL e configurei o SSL nele, deu certo, fiz a conexão e fiz uma consulta, agora estou na parte de atualização, me diga uma coisa, suponhamos que eu queira atualizar apenas o preço de um produto, eu preciso passar o XML inteiro com todos os dados do produto?

    Para atualização de dados e para inserção de novos registros eu uso sempre o PUT?

    Desde já mais uma vez muito obrigado pela atenção.

  • Eduardo disse:

    Eu estou com a mesma necessidade, já tenho o Lazarus instalado e todas as opções acima configuradas. Pequei inclusive seu exemlosync-prestashop-embapel-master porem não consigo me conectar com o prestashop, sempre recebo a mensagem:

    ODBC error details: LastReturnCode: SQL_ERROR; Record 1: SqlState: IM002; NativeError: 0; Message: [Microsoft][ODBC Driver Manager] Nome da fonte de dados n?o encontrado e nenhum driver padr?o especificado

    Será que vc poderia me dar uma ajuda?

    • Bom dia Eduardo! O exemplo que você pegou faz conexão com um banco de dados MDB (access). Esse erro não é da integração com a API, é justamente porque ele não encontrou a configuração ODBC responsável pela conexão com o banco. Pra corrigir isso você pode remover todos os componentes relativos à essa conexão (se vc não for precisar).

      • Eduardo disse:

        Frederico, em primeiro lugar, obrigado pela atenção…

        Eu separei uma parte do código para facilitar o entendimento, veja:
        procedure TForm1.BitBtn1Click(Sender: TObject);
        var resposta : String;
        httpClient : TIdHTTP;
        begin
        httpClient := TIdHTTP.Create(nil);
        with httpClient do
        begin
        Request.CustomHeaders.Clear;
        ConnectTimeout := 5000;
        ReadTimeout := 100000;
        Request.Connection := ‘Keep-Alive’;
        Request.ContentEncoding := ‘utf-8′;
        end;
        resposta := httpClient.Get(edtDomain.text+’/api/products/’+’description’+’?output_format=JSON&ws_key=’+edtKey.text);
        showmessage( resposta );
        httpClient.Free;
        end;

        porém, na linha:

        resposta := httpClient.Get(edtDomain.text+’/api/products/’+’description’+’?

        ele me retorna o erro:

        Error connecting with SSL.
        error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure.

        E eu não achei onde configurar o SSL no httpClient, será que vc poderia me dar alguma dica?

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *